Hooks and Handlers - Denire/jaicf-template-for-jaicp-developers GitHub Wiki

Hooks & ErrorHandlers

Во втором практическом задании был вопрос со звездочкой:

какой запрос в игре сломает её?

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

val userValue = request.input.toInt()

Чтобы избежать этого, мы, конечно, можем поставить проверку или блок try/catch. А ещё лучше сделать не только это, а ещё и подстраховаться по полной программе - добавить специальный обработчик, который сработает при ошибке, примерно при такой, которая была у нас. Это нужно для того, чтобы работа бота не прекращалась полностью и впечатление от работы не испортилось. Также можно снабдить этот обработчик небольшой инструкцией для пользователя, что случилось и что делать дальше.

Поможет нам в этом такая конструкция как hooks. Аналог в JAICP DSL - preProcess, postProcess.

val mainScenario = Scenario {

    handle<ActionErrorHook> {
        reactions.say("ПОПАВСЯ!")
    }
}

Хуки в JAICF

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

Хуки - они как в JAICP, только их больше и называются они чуток по-другому.

Пользователи JAICP знакомы с концепцией хуков, если когда-либо пользовались функциями preProcess, postProcess и другими. Следующий блок кода выполняется перед каждым запросом и проставляет переменную volume к дефолтному значению, если она не определена.

bind("preProcess", function($context) {
    if (!$context.session.volume) {
        $context.session.volume = DEFAULT_VOLUME;
    }
});

Аналогично ее можно написать и на JAICF:

val MyScenario = Scenario {
	handle<BeforeProcessHook> {
		if (context.session["volume"] == null){
			context.session["volume"] = DEFAULT_VOLUME
		}
	}
}

Так называемые хуки могут срабатывать не только на ошибку, но и:

  • сразу после получения запроса (BotRequestHook)
  • перед обработкой каждого запроса (BeforeProcessHook)
  • перед обработкой стейтов (BeforeActivationHook)
  • перед выполнением блока action (BeforeActionHook)
  • после обработки каждого запроса(AfterActionHook)
  • после выполнения блока action (AfterProcessHook)