Глава 6 Повышаем стабильность работы бота

В шестой главе нашего руководства мы сосредоточимся на повышении стабильности работы вашего Telegram-бота. Здесь вы узнаете, как обеспечить надежную и бесперебойную работу бота, предотвращая сбои и улучшая его производительность.

Мы рассмотрим стратегии мониторинга и поддержки стабильности, включая методы отладки и устранения ошибок. Вы изучите, как настроить системы для автоматического обнаружения и исправления проблем, что поможет вашему боту функционировать эффективно даже в сложных условиях.

Эта глава даст вам ключевые инструменты и техники для поддержания высокого уровня надежности вашего бота. Надеюсь, что эти рекомендации помогут вам создать более устойчивый и высококачественный продукт.

6.1 Конструкция tryCatch()

Повысить работоспособность вашего бота поможет конструкция tryCatch(). Данная конструкция имеет следующий синтаксис:

tryCatch(expr = {
  
    ~ Тут код который будет выполняться ~
  
}, 
  error = function(err) {
    
    ~ код который будет выполняться в случае возникновения ошибки в блоке expr ~
    
  }, 
  finally = {
    
    ~ Код который будет выполняться в любом случае, не зависимо от того закончилось выражение expr ошибкой или нет ~
    
  })

6.2 Логика работы конструкции tryCatch()

Из описанного синтаксиса понятно, что вам необходимо завернуть выражение в фигурные скобки в аргументе expr. Это выражение будет выполняться либо до тех пор, пока не встретится ошибка, либо если ошибки нет, оно будет выполнено полностью.

Если в выражении переданном в expr встречается ошибка, то конструкция tryCath() запустит анонимную функцию, которую вы передали в блоке error.

В любом случае, не зависимо от того, встретилась в выражении expr ошибка или нет, в завершении выполнения будет выполнен код, переданный в аргумент finally.

Если вы хотите более подробно узнать про конструкцию tryCatch() посмотрите этот видео урок.

6.3 Используем tryCatch() внутри бота

По большому счёту вы можете использовать tryCatch() внутри каждой функции вашего бота. Но можно убить всех зайцев одним выстрелом.

В разработке ботов слабым местом является пуллинг, т.е. метод updater$start_polling(). Пуллинг - это бесконечный цикл, именно он выполняется всё время работы бота, и даёт сбой если пользователь неправильно использовал бота, или API Telegram не отправил вам ответ. Соответственно если завернуть пуллинг в tryCatch(), и перезапускать вашего бота в бота в блоке finally то при любой ошибке он будет самостоятельно перезапускаться.

Перед перезапуском бота не забывайте очистить его апдейты, что бы избавиться от ошибки, которая вызвала падение бота.

Выглядеть такой пуллинг будет следующим образом:

tryCatch(
  
  # запускаем пуллинг
  expr = updater$start_polling(), 
  
  # действия при ошибке пуллинга
  error = function(err) {
    
    # бот для оповещения
    bot <- Bot(token = bot_token("Токен вашего бота"))
    
    # чат для оповещения
    chat_id <- "Идентификатор чата в который необходимо отправить сообщение"
    
    # сообщение
    msg <- str_glue("*Бот упал*: Ошибка (_{err$message}_).")
    
    bot$sendMessage(chat_id = chat_id, 
                    text = msg,
                    parse_mode = 'Markdown')
    
    # очищаем полученный апдейт бота, который вызвал ошибку
    updater$bot$clean_updates()
    
    # информация о том, что бот будет перезапущен
    bot$sendMessage(chat_id = chat_id, 
                    text = str_glue('*Перезапускаю бота* в {Sys.time()}'),
                    parse_mode = 'Markdown')

    
  }, 
  # действия которые будут выполненны в любом случае
  finally = {
    
    # останавливаем пулинг
    updater$stop_polling()
        
    # перезапускаем скрипт бота
    source('C:\\telegram_bot\\my_bot.R') 

  }
)

В приведённом выше коде вам необходимо подставить токен созданного вами бота, и указать ID чата, в который бот будет отправлять уведомление о падении пуллинга.

В блок expr мы завернули процесс пуллинга, таким образом он постоянно контролируется конструкцией tryCatch.

Далее в блок error мы передали безымянную функцию, которая принимает всего один аргумент err, т.е. саму ошибку. Сообщение об ошибке мы получаем через err$message, и отправляем в указанный чат. С помощью updater$bot$clean_updates() мы очищаем очередь апдейтов бота, т.к. последний апдейт вызвал ошибку и падение нашего бота.

В блоке finally мы останавливаем пуллинг, и командой source('C:\\telegram_bot\\my_bot.R') занова запускаем скрипт с ботом.

Такая схема позволяет боту очищаться и подниматься при любой ошибке пуллинга.

Очищать апдейты бота с помощью комманды updater$bot$clean_updates() можно так же и при запуске бота, указав эту команду сразу, после инициализации объекта бота.

6.4 Заключение

Отлично! Вы повысили стабильность работы вашего бота и теперь можете уверенно справляться с потенциальными проблемами. В следующей главе мы внедрим асинхронные операции, чтобы улучшить производительность вашего бота и сделать его более масштабируемым. Подготовьтесь к погружению в мир асинхронного программирования!