Я пишу приложение с TypeScript, а также с Koa 2.
Однако проблема, с которой я сталкиваюсь, заключается в том, что мой глобальный обработчик ошибок Koa не улавливает ошибки, которые были выброшены в моем приложении.
Возьмем, к примеру, следующее промежуточное ПО (это самое первое промежуточное ПО перед загрузкой каких-либо маршрутов):
app.use(async(ctx, next) => {
console.log("ErrorHandler loaded...");
try {
console.log("Trying for error...");
await next();
} catch (err) {
console.log("Caught error...");
ctx.status = err.status || 500;
ctx.response.body = "Error: " + err.message;
}
});
При доступе к моим маршрутам я вижу, что обработчик ошибок загружен и работает блок try
.
Однако, если я выдаю ошибку в маршруте (независимо от того, использую ли я throw
или ctx.throw
), все, что я получаю, это сообщение об ошибке по умолчанию. справиться с этим.
Теперь рассмотрим следующий транспилированный JavaScript:
app.use((ctx, next) => __awaiter(this, void 0, void 0, function* () {
console.log("ErrorHandler loaded...");
try {
console.log("Trying for error...");
yield next();
}
catch (err) {
console.log("Caught error...");
ctx.status = err.status || 500;
ctx.response.body = "Error: " + err.message;
}
}));
Вопрос двоякий:
- Мое приложение не может поймать выброшенные ошибки из-за транспиляции? Я имею в виду, будет ли это работать, если транспилируемый JavaScript будет использовать ключевые слова
async
иawait
, а не транспилировать его в генераторы, использующиеyield
? - Если вышесказанное верно: есть ли способ писать приложения Koa 2 с помощью TypeScript сейчас?
Редактировать
Я нашел решение, чтобы мои ошибки выбрасывались, но я до сих пор не понимаю, почему Koa их не ловит.
Этот цикл for of
выполняет итерацию массива контроллеров, которые я загружаю динамически. Для каждого контроллера я привязываю соответствующий метод (action.method) класса (action.target) к маршруту (action.route), используя указанный глагол Http (action.type).
Однако я также привязываю контекст к методу, чтобы гарантировать, что в соответствии с соглашениями Koa this
привязан к Context
:
for (let action of actionMetadata) {
router[action.type.toLowerCase()](action.route, (ctx, next) => {
(new action.target)[action.method].bind(ctx)(ctx, next);
});
}
Вышеприведенное вызывает проблему, когда ошибки не обнаруживаются.
Для сравнения, приведенный ниже код работает: ошибки теперь перехватываются Koa. Но это означает, что this
теперь уже не Context
.
Я могу смириться с этим, так как Context
является первым параметром в моих маршрутах, но я не понимаю, почему ошибка не перехватывается, поскольку все промежуточное ПО, следующее за обработчиком ошибок (это мое самое первое промежуточное ПО), должно работать в его блоке try
:
for (let action of actionMetadata) {
router[action.type.toLowerCase()](action.route, (new action.target )[action.method]);
}
this
, тогда какой смысл иметь эти функции в классе? - person Nitzan Tomer   schedule 22.08.2016@Route("/view/:id", HttpVerb.Get)
. К последнему пункту: нет никакого смысла - это был чистый пережиток моей попытки следовать соглашениям Коа.this
. Как я уже сказал: ctx — это первый параметр, и мне не нужно, чтобыthis
был контекстом. Помимо выбора дизайна, я думаю, мне просто трудно понять, почему первая настройка не перехватывает выброшенные исключения, поскольку нет дополнительныхtry
, которые потенциально могли бы их поглотить. - person JDR   schedule 22.08.2016