From 3f6c27529886973467e732ee33443dddfa32331d Mon Sep 17 00:00:00 2001 From: maxpozdeev Date: Wed, 29 Mar 2023 13:48:55 +0300 Subject: [PATCH] little more debug info in telegram notifications --- src/ext/notifications/class.controller.php | 3 +- src/ext/notifications/class.sender.php | 16 ++---- src/ext/notifications/class.telegramapi.php | 64 +++++++++++++++++---- src/ext/notifications/extension.json | 2 +- src/ext/notifications/loader.php | 11 +++- 5 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/ext/notifications/class.controller.php b/src/ext/notifications/class.controller.php index 98a6f83..a365583 100644 --- a/src/ext/notifications/class.controller.php +++ b/src/ext/notifications/class.controller.php @@ -2,7 +2,7 @@ /* This file is a part of myTinyTodo. - (C) Copyright 2022 Max Pozdeev + (C) Copyright 2022-2023 Max Pozdeev Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. */ @@ -42,6 +42,7 @@ class Controller extends \ApiController // Read messages since last check $maxId = $prefs['lastUpdateId'] ?? 0; $api = new TelegramApi($token); + $api->logApiErrors = true; $updates = $api->getUpdates([ 'offset' => $maxId + 1, 'allowed_updates' => ['message'] diff --git a/src/ext/notifications/class.sender.php b/src/ext/notifications/class.sender.php index 770ef6f..cb00a75 100644 --- a/src/ext/notifications/class.sender.php +++ b/src/ext/notifications/class.sender.php @@ -2,7 +2,7 @@ /* This file is a part of myTinyTodo. - (C) Copyright 2022 Max Pozdeev + (C) Copyright 2022-2023 Max Pozdeev Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. */ @@ -147,6 +147,7 @@ class Sender return; } $api = new TelegramApi($this->prefs['token']); + $api->logApiErrors = true; $blockedChats = []; foreach ($this->prefs['chats'] as $chatId) { // try-catch? @@ -156,15 +157,10 @@ class Sender 'text' => $text, 'disable_web_page_preview' => true ]); - if (!$result && $api->lastError) { - if ($api->lastError['error_code'] == 403) { - // User has blocked the bot - $blockedChats[] = $chatId; - error_log("Bot is blocked in chat $chatId, chat will be deactivated"); - } - else { - error_log("Telegram API Error ". $api->lastError['error_code']. ": ". $api->lastError['description']); - } + if (!$result && $api->lastError && $api->lastError['error_code'] == 403) { + // User has blocked the bot + $blockedChats[] = $chatId; + error_log("Bot is blocked in chat $chatId, chat will be deactivated"); } } //We can remove blocked chats from settings diff --git a/src/ext/notifications/class.telegramapi.php b/src/ext/notifications/class.telegramapi.php index afe6d2a..524cf50 100644 --- a/src/ext/notifications/class.telegramapi.php +++ b/src/ext/notifications/class.telegramapi.php @@ -2,7 +2,7 @@ /* This file is a part of myTinyTodo. - (C) Copyright 2022 Max Pozdeev + (C) Copyright 2022-2023 Max Pozdeev Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. */ @@ -13,6 +13,8 @@ class TelegramApi private $token = ''; /** @var ?array $lastError */ public $lastError = null; + public $logApiErrors = false; + public $throwExceptionOnApiError = false; function __construct(string $token) { @@ -36,12 +38,32 @@ class TelegramApi private function makeGetRequest(string $method): ?array { + $options = array( + 'http' => array( + 'ignore_errors' => true + ) + ); + $context = stream_context_create($options); $this->lastError = null; - $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false); - if ($body === false) { - throw new \Exception("Failed to make request to Telegram API"); + $body = $err = null; + set_error_handler(function ($errno, $message, $file, $line) { + throw new \ErrorException($message, $errno, $errno, $file, $line); + }); + try { + $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false, $context); } - $decodedBody = $this->decodeBody($body); + catch (\Exception $e) { + $err = ini_get('html_errors') ? htmlspecialchars_decode($e->getMessage()) : $e->getMessage(); + } + restore_error_handler(); + if ($body === false || null !== $err) { + $msg = "Failed to make request to Telegram API ($method)". ($err ? ": $err" : ""); + if ($this->logApiErrors) { + error_log($msg); + } + throw new \Exception($msg); + } + $decodedBody = $this->decodeBody($body, $method); return $decodedBody['result'] ?? []; } @@ -58,28 +80,48 @@ class TelegramApi ); $context = stream_context_create($options); $this->lastError = null; - $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false, $context); - if ($body === false) { - throw new \Exception("Failed to make request to Telegram API"); + $body = $err = null; + set_error_handler(function ($errno, $message, $file, $line) { + throw new \ErrorException($message, $errno, $errno, $file, $line); + }); + try { + $body = @file_get_contents('https://api.telegram.org/bot'. $this->token .'/'. $method, false, $context); } - $decodedBody = $this->decodeBody($body); + catch (\Exception $e) { + $err = ini_get('html_errors') ? htmlspecialchars_decode($e->getMessage()) : $e->getMessage(); + } + restore_error_handler(); + if ($body === false || null !== $err) { + $msg = "Failed to make request to Telegram API ($method)". ($err ? ": $err" : ""); + if ($this->logApiErrors) { + error_log($msg); + } + throw new \Exception($msg); + } + $decodedBody = $this->decodeBody($body, $method); return $decodedBody['result'] ?? []; } - private function decodeBody(string $body): array + private function decodeBody(string $body, string $method = ''): array { $decodedBody = json_decode($body, true); if (!is_array($decodedBody)) { $decodedBody = []; } if (!isset($decodedBody['ok'])) { - throw new \Exception("Telegram API Error"); + throw new \Exception("Telegram API ($method) Error"); } if ($decodedBody['ok'] === false) { $this->lastError = [ 'error_code' => $decodedBody['error_code'] ?? 0, 'description' => ($decodedBody['description'] ?? '') ]; + if ($this->logApiErrors) { + error_log("Telegram API ($method) Error ". $this->lastError['error_code']. "): ". $this->lastError['description']); + } + if ($this->throwExceptionOnApiError) { + throw new \Exception("Telegram API ($method) Error ". $this->lastError['error_code']. ": ". $this->lastError['description']); + } } return $decodedBody; } diff --git a/src/ext/notifications/extension.json b/src/ext/notifications/extension.json index 5dfa7f0..592b5e7 100644 --- a/src/ext/notifications/extension.json +++ b/src/ext/notifications/extension.json @@ -1,6 +1,6 @@ { "bundleId": "notifications", "name": "Notifications", - "version": "1.0", + "version": "1.0.1", "description": "Notify about new tasks and lists on e-mail or telegram" } diff --git a/src/ext/notifications/loader.php b/src/ext/notifications/loader.php index eced61a..60c93b7 100644 --- a/src/ext/notifications/loader.php +++ b/src/ext/notifications/loader.php @@ -2,7 +2,7 @@ /* This file is a part of myTinyTodo. - (C) Copyright 2022 Max Pozdeev + (C) Copyright 2022-2023 Max Pozdeev Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. */ @@ -176,6 +176,8 @@ EOD; // validate token if ($token != '' && !$prefs['validToken']) { $api = new TelegramApi($token); + $api->logApiErrors = true; + $api->throwExceptionOnApiError = true; try { $result = $api->getMe(); if ($result && isset($result['username'])) { @@ -184,8 +186,11 @@ EOD; $prefs['validToken'] = true; } catch (Exception $e) { - error_log($e->getMessage()); - $outMessage = __('notifications.no_bot_info');; + $prefs['token'] = ''; + $outMessage = __('notifications.no_bot_info'); + if (MTT_DEBUG) { + $outMessage .= " (". $e->getMessage(). ")"; + } return false; } }