mirror of
https://github.com/danog/TelegramApiServer.git
synced 2024-11-26 11:54:42 +01:00
Feat: uncaught errors notification
This commit is contained in:
parent
3d6a97d4cf
commit
d543b629a2
@ -15,7 +15,7 @@ TIMEZONE=UTC
|
||||
# VALUE IN SECOND
|
||||
# DECREASE TO REDUCE LATENCY, INCREASE TO REDUCE LOAD ON SERVER.
|
||||
# SET to 0 to DISABLE
|
||||
REQUESTS_BULK_INTERVAL=0.5
|
||||
REQUESTS_BULK_INTERVAL=0.0
|
||||
|
||||
# List of allowed clients. Separate with comma.
|
||||
# Leave blanc, to allow requests from all IP (THIS WILL MAKE API UNSECURE!)
|
||||
@ -67,4 +67,11 @@ DB_SERIALIZER=serialize
|
||||
# Enable to add cache info about users to database. Disable if you only read data from channels.
|
||||
DB_ENABLE_MIN_DATABASE=0
|
||||
# Enable file metadata cache
|
||||
DB_ENABLE_FILE_REFERENCE_DATABASE=0
|
||||
DB_ENABLE_FILE_REFERENCE_DATABASE=0
|
||||
|
||||
ERROR_NOTIFICATION_BOT_TOKEN=
|
||||
#User id or Chat id or username of the target channel to send error messages. Comma separated
|
||||
#Example: 123456,@sometestchannel
|
||||
ERROR_NOTIFICATION_PEERS=
|
||||
# Program will continue to work after fatal error (not recommended)
|
||||
RESUME_ON_ERROR=0
|
11
.env.example
11
.env.example
@ -16,7 +16,7 @@ TIMEZONE=UTC
|
||||
# VALUE IN SECOND
|
||||
# DECREASE TO REDUCE LATENCY, INCREASE TO REDUCE LOAD ON SERVER.
|
||||
# SET to 0 to DISABLE
|
||||
REQUESTS_BULK_INTERVAL=0.5
|
||||
REQUESTS_BULK_INTERVAL=0.0
|
||||
|
||||
# List of allowed clients. Separate with comma.
|
||||
# Leave blanc, to allow requests from all IP (THIS WILL MAKE API UNSECURE!)
|
||||
@ -65,4 +65,11 @@ DB_SERIALIZER=serialize
|
||||
# Enable to add cache info about users to database. Disable if you only read data from channels.
|
||||
DB_ENABLE_MIN_DATABASE=0
|
||||
# Enable file metadata cache
|
||||
DB_ENABLE_FILE_REFERENCE_DATABASE=0
|
||||
DB_ENABLE_FILE_REFERENCE_DATABASE=0
|
||||
|
||||
ERROR_NOTIFICATION_BOT_TOKEN=
|
||||
#User id or Chat id or username of the target channel to send error messages. Comma separated
|
||||
#Example: 123456,@sometestchannel
|
||||
ERROR_NOTIFICATION_PEERS=
|
||||
# Program will continue to work after fatal error (not recommended)
|
||||
RESUME_ON_ERROR=0
|
@ -27,6 +27,7 @@
|
||||
"php": "^8.1",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-curl": "*",
|
||||
"amphp/http-server": "^v3",
|
||||
"amphp/http": "^v2",
|
||||
"amphp/http-server-router": "^2",
|
||||
|
13
config.php
13
config.php
@ -9,6 +9,19 @@ $settings = [
|
||||
'port' => (int)getenv('SERVER_PORT'),
|
||||
'real_ip_header' => (string)(getenv('REAL_IP_HEADER') ?? ''),
|
||||
],
|
||||
'error' => [
|
||||
'bot_token' => (string)getenv('ERROR_NOTIFICATION_BOT_TOKEN'),
|
||||
'peers' => array_filter(
|
||||
array_map(
|
||||
static function(string $peer): string|int {
|
||||
$peer = trim($peer);
|
||||
return is_numeric($peer) ? (int)$peer : $peer;
|
||||
},
|
||||
explode(',', (string)getenv('ERROR_NOTIFICATION_PEERS'))
|
||||
),
|
||||
),
|
||||
'resume_on_error' => ((bool)getenv('RESUME_ON_ERROR'))
|
||||
],
|
||||
'telegram' => [
|
||||
'app_info' => [ // obtained in https://my.telegram.org
|
||||
'api_id' => (int)getenv('TELEGRAM_API_ID'),
|
||||
|
@ -10,9 +10,11 @@ use danog\MadelineProto\SettingsAbstract;
|
||||
use InvalidArgumentException;
|
||||
use Psr\Log\LogLevel;
|
||||
use ReflectionProperty;
|
||||
use Revolt\EventLoop;
|
||||
use RuntimeException;
|
||||
use TelegramApiServer\EventObservers\EventHandler;
|
||||
use TelegramApiServer\EventObservers\EventObserver;
|
||||
use function Amp\async;
|
||||
use function Amp\delay;
|
||||
|
||||
class Client
|
||||
{
|
||||
@ -32,6 +34,8 @@ class Client
|
||||
{
|
||||
warning(PHP_EOL . 'Starting MadelineProto...' . PHP_EOL);
|
||||
|
||||
$this->setFatalErrorHandler();
|
||||
|
||||
foreach ($sessionFiles as $file) {
|
||||
$sessionName = Files::getSessionName($file);
|
||||
$this->addSession($sessionName);
|
||||
@ -160,7 +164,8 @@ class Client
|
||||
return $wrapper;
|
||||
}
|
||||
|
||||
private static function getSettingsFromArray(string $session, array $settings, SettingsAbstract $settingsObject = new Settings()): SettingsAbstract {
|
||||
private static function getSettingsFromArray(string $session, array $settings, SettingsAbstract $settingsObject = new Settings()): SettingsAbstract
|
||||
{
|
||||
foreach ($settings as $key => $value) {
|
||||
if (is_array($value) && $key !== 'proxies') {
|
||||
if ($key === 'db' && isset($value['type'])) {
|
||||
@ -198,5 +203,65 @@ class Client
|
||||
return $settingsObject;
|
||||
}
|
||||
|
||||
private function setFatalErrorHandler(): void
|
||||
{
|
||||
|
||||
$token = Config::getInstance()->get('error.bot_token');
|
||||
$peers = Config::getInstance()->get('error.peers');
|
||||
$resume = Config::getInstance()->get('error.resume_on_error');
|
||||
|
||||
$currentHandler = EventLoop::getErrorHandler();
|
||||
EventLoop::setErrorHandler(static fn(\Throwable $e) => self::errorHandler($e, $currentHandler, $token, $peers, $resume));
|
||||
}
|
||||
|
||||
private static function errorHandler(\Throwable $e, ?callable $currentHandler, string $token, array $peers, bool $resume): void {
|
||||
if ($currentHandler) {
|
||||
$currentHandler($e);
|
||||
}
|
||||
if ($e->getPrevious()) {
|
||||
self::errorHandler($e->getPrevious(), $currentHandler, $token, $peers, true);
|
||||
}
|
||||
if ($peers && $token) {
|
||||
try {
|
||||
$ch = curl_init("https://api.telegram.org/bot$token/sendMessage");
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT,1);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
|
||||
|
||||
foreach ($peers as $peer) {
|
||||
$exceptionArray = Logger::getExceptionAsArray($e);
|
||||
unset($exceptionArray['previous_exception']);
|
||||
|
||||
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
||||
'chat_id' => $peer,
|
||||
'text' => "```json\n" .
|
||||
json_encode($exceptionArray, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE|JSON_PRETTY_PRINT) .
|
||||
"\n```"
|
||||
,
|
||||
'parse_mode' => 'MarkdownV2',
|
||||
]));
|
||||
|
||||
$response = curl_exec($ch);
|
||||
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) !== 200) {
|
||||
Logger::getInstance()->error('Error notification bot response', [
|
||||
'response' => $response,
|
||||
'error_code' => curl_errno($ch),
|
||||
'error' => curl_error($ch),
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
} catch (\Throwable $curlException) {
|
||||
Logger::getInstance()->error($curlException);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$resume) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ class Logger extends AbstractLogger
|
||||
'line' => $exception->getLine(),
|
||||
'code' => $exception->getCode(),
|
||||
'backtrace' => array_slice($exception->getTrace(), 0, 3),
|
||||
'previous exception' => $exception->getPrevious(),
|
||||
'previous_exception' => $exception->getPrevious(),
|
||||
];
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user