Обробка помилок
Кожна помилка, яку може спричинити проміжний обробник, буде перехоплена grammY. Для обробки помилок слід встановити власний обробник помилок.
Найголовніше, цей розділ навчить вас, як перехоплювати помилки, які можуть виникати.
Після цього ми розглянемо всі три типи помилок, з якими може зіткнутися ваш бот.
Назва | Значення |
---|---|
Bot | Обʼєкт Error, який огортає будь-яку помилку, створену вашим проміжним обробником: наприклад, наступні дві помилки |
Grammy | Викидається, якщо сервер Bot API повертає ok: . Отже, ваш запит до API був недійсним і не вдався |
Http | Викидається, якщо сервер Bot API недоступний |
Більш просунутий механізм обробки помилок можна знайти тут.
Перехоплення помилок
Спосіб перехоплення помилок залежатиме від ваших налаштувань.
Тривале опитування
Якщо ви запускаєте свого бота через bot
або використовуєте плагін для конкурентності (runner), то вам треба встановити обробник помилок через bot
.
У grammY вже встановлений основний обробник помилок, який зупиняє бота, якщо він запущений через bot
. Потім він повторно викидає помилку. Що буде далі, залежить від платформи. Ось чому ви повинні встановити обробник помилок через bot
.
Наприклад:
bot.catch((err) => {
const ctx = err.ctx;
console.error(`Помилка під час обробки оновлення ${ctx.update.update_id}:`);
const e = err.error;
if (e instanceof GrammyError) {
console.error("Помилка в запиті:", e.description);
} else if (e instanceof HttpError) {
console.error("Не вдалося звʼязатися з Telegram:", e);
} else {
console.error("Невідома помилка:", e);
}
});
2
3
4
5
6
7
8
9
10
11
12
Вебхуки
Якщо ви запускаєте свого бота через вебхуки, grammY передасть помилку фреймворку, який ви використовуєте, наприклад, express
. Ви повинні обробляти помилки відповідно до прийнятих у цьому фреймворку домовленостей.
Обʼєкт BotError
Обʼєкт Bot
обʼєднує викинуту помилку з відповідним обʼєктом контексту, який спричинив викид помилки. Це працює наступним чином.
Яка б помилка не сталася під час обробки оновлення, grammY перехопить викинуту помилку за вас. Часто буває корисно отримати доступ до обʼєкта контексту, який спричинив помилку.
grammY жодним чином не змінює викинуту помилку, а натомість загортає її в екземпляр Bot
. Враховуючи, що отриманий обʼєкт має назву err
, ви можете отримати доступ до оригінальної помилки через err
. Ви можете отримати доступ до відповідного обʼєкта контексту через err
.
Ознайомтеся з класом Bot
у довідці API grammY.
Обʼєкт GrammyError
Якщо виклик методу API, як-от send
, не вдається, grammY викине Grammy
. Зауважте, що екземпляри Grammy
також будуть загорнуті в Bot
, якщо вони викинуті в проміжному обробнику.
Викинутий Grammy
означає, що відповідний запит API не виконано. Помилка надає доступ до коду та опису помилки, яку повертає сервер Telegram.
Ознайомтеся з класом Grammy
у довідці API grammY.
Обʼєкт HttpError
Помилка HttpError викидається, якщо не вдається виконати мережевий запит. Це означає, що grammY не зміг звʼязатися з сервером Bot API. Обʼєкт помилки містить інформацію про те, чому запит не вдалося виконати, яка доступна у властивості error
.
Ви рідко будете бачити цю помилку, хіба що ваша мережева інфраструктура нестабільна або сервер Bot API вашого бота тимчасово не працює.
Зауважте, що якщо звʼязатися з сервером Bot API можна, але він повертає
ok:
для певного виклику методу, то буде викинута помилкаfalse Grammy
.Error
Ознайомтеся з класом Http
у довідці API grammY.
Межі помилок
Це тема для просунутих користувачів, яка здебільшого корисна для великих ботів. Якщо ви відносно новачок у grammY, просто пропустіть решту цього розділу.
Якщо ви розділите свою кодову базу на різні частини, межі помилок дозволять вам встановити різні обробники помилок для різних частин ваших проміжних обробників. Це досягається шляхом перехоплення помилок для певних проміжних обробників. Іншими словами, якщо помилка виникає в спеціально захищеній частині проміжних обробників, вона не зможе вийти за межі цієї частини. Замість цього буде викликано спеціальний обробник помилок, а ті проміжні обробники, які охоплені цим обробником, зроблять вигляд, що обробка завершилася успішно. Це функція системи проміжних обробників grammY, тому для межі помилок немає значення як запущений бот, чи за допомогою вебхуків, чи за допомогою тривалого опитування.
За бажанням ви можете дозволити виконанню проміжних обробників відновитися у звичайному режимі після обробки помилки, продовжуючи виконання безпосередньо після межі помилок. У цьому випадку охоплений проміжний обробник не тільки діє так, ніби він був успішно завершений, але також передає потік керування наступному проміжному обробнику, який було встановлено після межі помилок. Отже, це виглядає так, ніби проміжний обробник всередині межі помилок викликав next
.
const bot = new Bot("");
bot.use(/* A */);
bot.use(/* B */);
const composer = new Composer();
composer.use(/* X */);
composer.use(/* Y */);
composer.use(/* Z */);
bot.errorBoundary(boundaryHandler /* , Q */).use(composer);
bot.use(/* C */);
bot.use(/* D */);
bot.catch(errorHandler);
function boundaryHandler(err: BotError, next: NextFunction) {
console.error("Помилка в Q, X, Y або Z!", err);
/*
* Можемо викликати `next`, якщо хочемо запустити
* проміжний обробник, позначений як C, у разі помилки:
*/
// await next()
}
function errorHandler(err: BotError) {
console.error("Помилка в A, B, C або D!", err);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
У наведеному вище прикладі boundary
буде викликано для:
- Усіх проміжних обробників, які передаються до
bot
після.error Boundary boundary
, тобтоHandler Q
. - Усіх проміжних обробників, які встановлено на згодом встановлений екземпляр composer:
X
,Y
іZ
.
Щодо 2-го пункту, ви можете перейти до розширеного пояснення проміжних обробників, щоб дізнатися, як потік керування працює у grammY.
Ви також можете застосувати межу помилок до composer без виклику bot
:
const composer = new Composer();
const protected = composer.errorBoundary(boundaryHandler);
protected.use(/* B */);
bot.use(composer);
bot.use(/* C */);
bot.catch(errorHandler);
function boundaryHandler(err: BotError, next: NextFunction) {
console.error("Помилка в B!", err);
}
function errorHandler(err: BotError) {
console.error("Помилка в C!", err);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
boundary
з наведеного вище прикладу буде викликано для проміжного обробника, привʼязаного до protected
.
Якщо ви дійсно хочете, щоб помилка перетнула межу, тобто передати її назовні, ви можете повторно викинути помилку у своєму обробнику помилок. Помилка буде передана наступній навколишній межі.
У певному сенсі ви можете розглядати обробник помилок, встановлений через bot
, як останню межу помилки.