Функция предназначена для установки обработчиков preProcess и postProcess.
Обработчики работают только если функция объявлена внутри тега init:.
Параметры
type— тип обработчика.handler— callback-функция с сигнатуройfunction($context)будет вызвана в соответствующий момент обработки запроса клиента.path— путь, к котор ому нужно привязать обработчик, по умолчанию/.name— короткое имя обработчика, его идентификатор.
Типы обработчиков type:
preMatch— вызывается перед классификатором интентов (матчером).preMatchможет принудительно отменить выполнение матчера, если выставить переменную$temp.targetState = "..".preProcess— вызывается после классификатора, но перед началом выполнения реакцийtargetState.postProcess— вызывается после завершения обработки запроса.onScriptError— вызывается, если выполнение сценария прервано по ошибке выполнения JS-кода. После обработчикаonScriptErrorможет быть выполненpostProcess.onAnyError— вызывается, если выполнение сценария прервано по какой-либо ошибке, в том числе внутренней ошибке сервера. Вызов происходит не при каждом типе ошибок.
После обработчика onAnyError не выполняется postProcess.
Подробнее об обработчиках onScriptError и onAnyError
onScriptError
Вызывается, если ошибка возникла в ходе выполнения JS-кода. В коде отлавливаются ошибки, из которых берется сообщение и дублируется в onScriptError. По возможности указывается место, где в JS-коде возникла ошибка.
Рассмотрим сценарий:
theme: /
state: error test
q!: error test
script:
someError(); # вызовет ошибку, так как мы не определяли функцию someError()
Здесь будет вызвана ошибка типа ReferenceError с сообщением ““someError” is not defined”, так как не была определена функция someError(). Эта ошибка отлавливается при помощи onScriptError.
onAnyError
Вызывается в нескольких случаях:
- Возникла ошибка, повлекшая
onScriptError. Но в сценарии смартапа нет обработчика ошибок, который отлавливает случаиonScriptError. - Возникла любая другая ошибка в процессе обработки запроса.
Рассмотрим тип ошибок DialogException. Такая ошибка возникает в нескольких случаях:
- Для отправленного запроса не был определен
state. Сообщение об ошибке:"No target state was determined for query". - Если смартап попадает в бесконечный цикл. Например, в
postProcessобработке перенаправляем смартап на стейт, а потом снова в тот жеpostProcess. Сообщение об ошибке:"Infinite loop was detected for state <statename> in postProcess transition". - Если осуществляется переход
transitionв несуществующий стейт. Сообщение об ошибке:"State not found for path <statename>".
Подробнее об обработчике preMatch
В preMatch есть возможность изменить $request.query.
Для успешного изменения $request.query в файле chatbot.yaml должно быть прописано в блоке nlp: modifyRequestInPreMatch: true.
Пример сценария:
entryPoint: main.sc
nlp:
modifyRequestInPreMatch: true
init:
var f = function(ctx) {
ctx.request.query = "новый текст";
}
$jsapi.bind({
type:"preMatch",
handler:f,
path:"/",
name:"modify query"
})
theme: /
state:
q!: *
a: {{ $parseTree.text }}
Примеры значений
- Использование
onAnyErrorпри динамическом формировании сообщения об ошибке.
Например, выдача случайного сообщения из 3 возможных:
init: bind('onAnyError', function ($context) {
var r = $jsapi.random(3);
if (r == 0) {
$reactions.answer('Что-то пошло не так');
} else if (r == 1) {
$reactions.answer('Все сломалось, нам очень жаль');
} else {
$reactions.answer('Произошла ошибка');
}
});
Формирование сообщения об ошибке:
init:
bind("onAnyError", function($context) {
if ($context.injector.testMode
&& $context.exception.message
&& $context.exception.message === 'No target state was determined for query') {
$reactions.answer("Для вопроса " + $context.request.query + " не найден стейт!");
}
});
theme:
state: Without CatchAll
q: Useless
a: Useless
onScriptErrorиспользуется для обработки исключений, возникших во время выполнения скрипта: из-за ошибки или выброшенных специально.
Рассмотрим пример в связке с http-запросами: в сценарии обрабатываем случай успешного выполнения запроса, для ошибочного создаем отдельный обработчик в onScriptError.
function callApi() {
var result = $http.get('https://example.com');
if (!result.isOk) {
throw {httpStatus: result.status};
}
return result.data;
}
...
state: ExternalApi
script:
var apiResult = callApi();
$reactions.answer("Result " + formatApiResult(apiResult));
...
init:
bind("onScriptError", function($context) {
if ($context.exception.httpStatus) {
$reactions.answer("Ошибка вызова внешнего сервиса. Код ошибки: " + $context.exception.httpStatus);
}
});