From 96ac1626dc1fc1ab996d28ed233fb9ef24596e47 Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 12 Apr 2024 16:40:12 +0530 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=99=84=20Print=20`StackTrace`=20along?= =?UTF-8?q?=20with=20`TelegramException`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/televerse/models/telegram_exception.dart | 12 ++++++++++-- lib/src/utils/http.dart | 6 +++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/src/televerse/models/telegram_exception.dart b/lib/src/televerse/models/telegram_exception.dart index 7b6cae88..0bc61970 100644 --- a/lib/src/televerse/models/telegram_exception.dart +++ b/lib/src/televerse/models/telegram_exception.dart @@ -40,8 +40,16 @@ class TelegramException implements Exception { /// Returns a string representation of the exception. @override String toString() { - return "TelegramException [$code]: ${description != null ? '($description)' : ''}\n" - "${parameters != null ? '\nParameters: $parameters' : ''}"; + String str = "TelegramException [$code]: "; + if (description != null) { + str += "($description)\n"; + } + if (parameters != null) { + str += "\nParameters: $parameters"; + } + + str += "\nStack Trace:\n$stackTrace"; + return str; } /// Returns true if the exception is a client exception. diff --git a/lib/src/utils/http.dart b/lib/src/utils/http.dart index 3095e085..952ac856 100644 --- a/lib/src/utils/http.dart +++ b/lib/src/utils/http.dart @@ -33,7 +33,7 @@ class _HttpClient { } // Throws formatted exception - void _dioCatch(Object? e) { + void _apiError(Object? e) { if (e is TelegramException) { throw e; } @@ -72,7 +72,7 @@ class _HttpClient { throw TelegramException.fromJson(resBody); } } catch (e) { - _dioCatch(e); + _apiError(e); } } @@ -106,7 +106,7 @@ class _HttpClient { throw TelegramException.fromJson(res); } } catch (e) { - _dioCatch(e); + _apiError(e); } } From 62d86ad32ba9bb16c2e0adccad4ddddfed6d230c Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 12 Apr 2024 16:41:34 +0530 Subject: [PATCH 2/5] =?UTF-8?q?=E2=98=80=EF=B8=8F=20Enhanced=20`LoggerOpti?= =?UTF-8?q?ons`=20and=20new=20`LoggerOptions.only`=20constructor?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/televerse/models/logger_options.dart | 40 ++++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/lib/src/televerse/models/logger_options.dart b/lib/src/televerse/models/logger_options.dart index b69f9e7a..6fb24a9d 100644 --- a/lib/src/televerse/models/logger_options.dart +++ b/lib/src/televerse/models/logger_options.dart @@ -31,6 +31,8 @@ class LoggerOptions { /// Creates a new [LoggerOptions] instance. This can be used to configure logging the /// request and response data Televerse makes and receives. /// + /// By default this constructor enabled logging all of the parameters such as `request`., `requestHeader`., `requestBody`., `responseHeader`., `responseBody`., error, and `stackTrace`. + /// /// - [request] - Print request [Options] /// - [requestHeader] - Print request header [Options.headers] /// - [requestBody] - Print request data [Options] @@ -54,6 +56,33 @@ class LoggerOptions { this.prettyPrint = true, }) : methods = methods ?? APIMethod.values; // Default all methods + /// Creates a new [LoggerOptions] instance with only specified configuration. + /// + /// All of the parameters are turned off by default. + /// + /// - [request] - Print request [Options] + /// - [requestHeader] - Print request header [Options.headers] + /// - [requestBody] - Print request data [Options] + /// - [responseHeader] - Print [Response.headers] + /// - [responseBody] - Print [Response.data] + /// - [error] - Print error message + /// - [stackTrace] - Print error stack trace [DioException.stackTrace] + /// - [logPrint] - Log printer; defaults print log to console. + /// - [methods] - Methods to be logged. + /// - [prettyPrint] - Whether to pretty print the response body + const LoggerOptions.only({ + this.request = false, + this.requestHeader = false, + this.requestBody = false, + this.responseHeader = false, + this.responseBody = false, + this.error = false, + this.stackTrace = false, + this.logPrint = _debugPrint, + List? methods, + this.prettyPrint = true, + }) : methods = methods ?? APIMethod.values; // Default all methods + /// Print request [Options] final bool request; @@ -76,7 +105,7 @@ class LoggerOptions { final bool stackTrace; /// Log printer; defaults print log to console. - final void Function(Object object) logPrint; + final void Function(Object? object) logPrint; /// Methods to be logged. final List methods; @@ -145,13 +174,16 @@ class LoggerOptions { isAllowed(APIMethod.method(path)); final error = allowed && this.error; if (error) { - logPrint("<-- Error -->"); - logPrint(e); + logPrint("--- [Logger]: Error ---"); + if (e.response != null) { + logPrint("Telegram Exception Occurred\n ${e.response}"); + logPrint(""); + } if (stackTrace) { logPrint("Stack Trace:"); logPrint(e.stackTrace); } - logPrint("<-- End Error -->"); + logPrint("--- [Logger]: End Error ---\n"); } return handler.next(e); }, From 27f0b8a2a380a8697eb1fef08e32afe11e4d28bc Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 12 Apr 2024 16:45:01 +0530 Subject: [PATCH 3/5] =?UTF-8?q?=E2=98=98=EF=B8=8F=20Pretty=20print=20the?= =?UTF-8?q?=20response=20data?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/televerse/models/logger_options.dart | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/src/televerse/models/logger_options.dart b/lib/src/televerse/models/logger_options.dart index 6fb24a9d..c7fa4da4 100644 --- a/lib/src/televerse/models/logger_options.dart +++ b/lib/src/televerse/models/logger_options.dart @@ -176,7 +176,10 @@ class LoggerOptions { if (error) { logPrint("--- [Logger]: Error ---"); if (e.response != null) { - logPrint("Telegram Exception Occurred\n ${e.response}"); + final encoded = JsonEncoder.withIndent(" ").convert( + e.response?.data, + ); + logPrint("Telegram Exception:\n$encoded"); logPrint(""); } if (stackTrace) { From f5f32192801f4d970348d9c92568ce6d201e5ec7 Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 12 Apr 2024 18:57:24 +0530 Subject: [PATCH 4/5] =?UTF-8?q?=F0=9F=8C=BB=20Added=20exception=20details?= =?UTF-8?q?=20and=20improved=20error=20logging?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/src/televerse/extras/tg_exceptions.dart | 212 +++++++++++++++++++ lib/src/televerse/models/logger_options.dart | 8 + lib/televerse.dart | 3 + 3 files changed, 223 insertions(+) create mode 100644 lib/src/televerse/extras/tg_exceptions.dart diff --git a/lib/src/televerse/extras/tg_exceptions.dart b/lib/src/televerse/extras/tg_exceptions.dart new file mode 100644 index 00000000..9d30b0b0 --- /dev/null +++ b/lib/src/televerse/extras/tg_exceptions.dart @@ -0,0 +1,212 @@ +part of '../../../televerse.dart'; + +/// Telegram Exceptions Database +/// +/// Thanks to https://github.com/TelegramBotAPI/errors for the collection of errors. +enum TGException { + /// Unauthorized exception + unauthorized._( + code: 401, + description: "Unauthorized", + reason: "Bot token is incorrect.", + help: + "Double check the Bot Token, and pass the correct Bot token to create the Bot instance.", + ), + + /// Chat Not Found + chatNotFound._( + code: 400, + description: "Bad Request: chat not found", + reason: "Passsed incorrect `chat_id` in.", + help: + "It is important to note that the Bot cannot initiate chat with a user. Bots can only send messages to already known chats. Double check the passed `chat_id` parameter.", + ), + + /// User not found + userNotFound._( + code: 400, + description: "Bad Request: user not found", + reason: "Incorrect `user_id` is passed with the request", + help: + "This exception is thrown when you try to promote a non-existent user in a chat or similar context. Double check if the `user_id` parameter in the request to fix this issue.", + ), + + /// Participant ID invalid + invalidParticipantId._( + code: 400, + description: "Bad Request: PARTICIPANT_ID_INVALID", + reason: "Invalid `user_id` prameter in the request.", + help: + "This exception usually occurs when trying to ban/restrict a non existent user in a chat. Double check the passed `user_id` parameter in the request.", + ), + + /// User is deactivated + deactivatedUser._( + code: 403, + description: "Forbidden: user is deactivated", + reason: + "You're trying to perform an action on a user account that has been deactivated or deleted", + help: "Make sure the `user_id` parameter in the request is correct.", + ), + + /// Forbidden: bot was kicked from the group chat + botIsKicked._( + code: 403, + description: "Forbidden: bot was kicked from the group chat", + reason: "Bot was kicked from the group chat", + help: + "The bot has been kicked from the group. You should not deal with this particular `chat_id`", + ), + + /// Forbidden: bot was blocked by the user + blockedByUser._( + code: 403, + description: "Forbidden: bot was blocked by the user", + reason: "The user have blocked the bot", + help: "You should not deal with this particular `chat_id`", + ), + + /// Forbidden: bot can't send messages to bots + botToBot._( + code: 403, + description: "Forbidden: bot can't send messages to bots", + reason: "You tried to send a message to another bot. This is not possible", + help: + "Bots cannot talk with bots. You should not deal with this particular `chat_id", + ), + + /// Too Many Requests: retry after X + tooManyRequest._( + code: 429, + description: r"Too Many Requests: retry after \d+", + reason: "You are hitting the API limit.", + help: + "All of the API endpoinds have its own rate limiting. The Bot API will not allow more than 30 messages per second or so. More information here: https://core.telegram.org/bots/faq#my-bot-is-hitting-limits-how-do-i-avoid-this", + ), + + /// Bad Request: group chat was migrated to a supergroup chat + migratedToSupergroup._( + code: 400, + description: "Bad Request: group chat was migrated to a supergroup chat", + reason: + "Occurs when a group chat has been converted/migrated to a supergroup", + help: + "Check the provided `chat_id` and make sure the new Super Group ID is passed.", + ), + + /// Bad Request: invalid file id + invalidFileId._( + code: 400, + description: "Bad Request: invalid file id", + reason: "The file id you are trying to retrieve doesn't exist.", + help: + "Make sure that you're passing the correct `file_id` to the request. Another possible solution is to check if the file exist using `getFile` call.", + ), + + /// Bad Request: message is not modified + messageIsNotModified._( + code: 400, + description: "Bad Request: message is not modified", + reason: "The current and new message text and reply markups are the same.", + help: + "Either change the text or change the InlineReplyMarkup of the speicifed Message.", + ), + + /// Conflict: terminated by other long poll or webhook + terminated._( + code: 409, + description: "Conflict: terminated by other long poll or webhook", + reason: + "You have already set up a webhook and are trying to get the updates via `getUpdates` ", + help: "DO NOT leave multiple Bot instances running.", + ), + + /// Bad Request: message text is empty + messageTextisEmpty._( + code: 400, + description: "Bad Request: message text is empty", + reason: "The message text is empty or not provided", + help: + "This exception is possibly occured in either `sendMessage`, `editMessageText`. You must set the `text` property to a valid value.", + ), + + /// Bad Request: wrong parameter action in request + invalidChatAction._( + code: 400, + description: "Bad Request: wrong parameter action in request", + reason: "Occurs when the action property value is invalid ", + help: + "Provide a valid value to the action property as specified in the documentation. (Use ChatAction enum).", + ), + + /// Bad Request: TOPIC_CLOSED + topicClosed._( + code: 400, + description: "Bad Request: TOPIC_CLOSED", + reason: + "The forum topic has been closed. Sending messages to this TOPIC is not allowed.", + help: + "Either set the `message_thread_id` to a valid open TOPIC id or make the bot an admin of the chat", + ), + + /// Bad Request: message thread not found + threadNotFound._( + code: 400, + description: "Bad Request: message thread not found", + reason: + "This occurs when bot is trying to send message to a non-existing thread.", + help: "Pass the correct id in message_thread_id parameter.", + ), + + /// Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first + webhookActiveCantLongPoll._( + code: 409, + description: + "Conflict: can't use getUpdates method while webhook is active; use deleteWebhook to delete the webhook first", + reason: "You are trying to use getUpdates while a webhook is active.", + help: "Use deleteWebhook to delete the webhook first.", + ), + + /// Bad Request: query is too old and response timeout expired or query ID is invalid + queryIsTooOldOrExpired._( + code: 400, + description: + "Bad Request: query is too old and response timeout expired or query ID is invalid", + reason: + "This exception occurs when you invoke the answerCallbackQuery method more than once for the same callback query or after the callback query has expired.", + help: + "To avoid this exception, ensure that you only call the `answerCallbackQuery` method once for each callback query and do so before the query expires.", + ), + ; + + /// Description of the exception + final String description; + + /// Status code for this kind of exception. + final int code; + + /// Human readable description or reason behind the exception + final String reason; + + /// Possible solution to fix this kind of exception. + final String help; + + /// Constructor + const TGException._({ + required this.code, + required this.description, + required this.help, + required this.reason, + }); + + /// Finds a TGException that matches the description. + static TGException? find(String description) { + try { + return TGException.values.firstWhere((e) { + return RegExp(e.description).hasMatch(description); + }); + } catch (_) { + return null; + } + } +} diff --git a/lib/src/televerse/models/logger_options.dart b/lib/src/televerse/models/logger_options.dart index c7fa4da4..f50ff2ea 100644 --- a/lib/src/televerse/models/logger_options.dart +++ b/lib/src/televerse/models/logger_options.dart @@ -181,6 +181,14 @@ class LoggerOptions { ); logPrint("Telegram Exception:\n$encoded"); logPrint(""); + final tge = TGException.find(e.response!.data["description"]); + if (tge != null) { + logPrint("Reason:"); + logPrint(" - ${tge.reason}\n"); + logPrint("Possible Solution:"); + logPrint(" - ${tge.help}"); + logPrint(""); + } } if (stackTrace) { logPrint("Stack Trace:"); diff --git a/lib/televerse.dart b/lib/televerse.dart index 11d0095c..7b1e0b83 100644 --- a/lib/televerse.dart +++ b/lib/televerse.dart @@ -58,6 +58,9 @@ part 'src/televerse/conversation/conversation_exception.dart'; part 'src/televerse/builders/inline_query_result_builder.dart'; part 'src/televerse/builders/message_content_generator.dart'; +/// Extras +part 'src/televerse/extras/tg_exceptions.dart'; + /// The main class of the library. /// /// This class is used to create a new bot instance. This is just a From d9cf810e00a3bdc2d254e93383fa81a6afdaf7da Mon Sep 17 00:00:00 2001 From: Sreelal TS Date: Fri, 12 Apr 2024 19:03:20 +0530 Subject: [PATCH 5/5] =?UTF-8?q?=F0=9F=9A=80=20Version=20&=20Logs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 7 +++++++ pubspec.yaml | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 65920a4b..0a0b2893 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# 1.15.8 + +- Introducing `TGException` enum which is a collection of different possible Telegram exceptions binded with their reasons and possible solutions. +- Added `LoggerOptions.only` method to turn on logging for ONLY specified actions. +- Prints resposne data if any on exception with Logger. +- Prints `StackTrace` along with uncaught `TelegramException` errors. + # 1.15.7 - `Context.args` will no longer return null. diff --git a/pubspec.yaml b/pubspec.yaml index a1c7fd68..3f940d40 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: televerse description: Televerse lets you create your own efficient Telegram bots with ease in Dart. Supports latest Telegram Bot API - 7.2! -version: 1.15.7 +version: 1.15.8 homepage: https://github.com/HeySreelal/televerse topics: - telegram