Могу ли я поймать ошибку из async без использования await?
могут ли ошибки из не ожидаемого асинхронного вызова быть пойманы, отправлены в оригинальную инкапсуляцию try/catch или вызвать необработанное исключение?
вот пример что я имею в виду:
async function fn1() {
console.log('executing fn1');
}
async function fn2() {
console.log('executing fn2');
throw new Error('from fn2');
}
async function test() {
try {
await fn1();
fn2();
}
catch(e) {
console.log('caught error inside test:', e);
}
}
test();
в этом случае ошибка, вызванная из fn2
будет проглочен молча, и определенно не пойман оригиналом try/catch
. Я считаю, что это ожидаемое поведение, так как fn2
скорее всего, отталкивается от цикла событий, чтобы закончить в какой-то момент в будущем, и test
не заботится, когда он заканчивается (что намеренно).
есть ли способ гарантировать, что ошибки не будут случайно проглочены такой структурой, как эта, не поставив try/catch
внутренний fn2
и делать что-то вроде испуская ошибка? Я бы даже согласился на необработанную ошибку, не зная, как ее поймать, я думаю-я не ожидаю, что брошенные ошибки будут типичным потоком программы с тем, что я пишу, но проглатывание ошибок делает его относительно раздражающим отлаживать.
примечание, Я использую Babel для транспилирования кода с помощью преобразования babel-runtime и выполнения его с помощью node.
2 ответов
работа с необработанными отклоненными собственными обещаниями (и async/await использует собственные обещания) - это функция, поддерживаемая теперь в V8. Он используется в последнем Chrome для вывода отладочной информации, когда отклоненное обещание необработано; попробуйте следующее в Вавилонское отражение:
async function executor() {
console.log("execute");
}
async function doStuff() {
console.log("do stuff");
throw new Error("omg");
}
function handleException() {
console.error("Exception handled");
}
(async function() {
try {
await executor();
doStuff();
} catch(e) {
handleException();
}
})()
вы видите, что, хотя исключение из doStuff()
теряется (потому что мы не используем await
когда мы называем это), Chrome регистрирует, что отклоненное обещание было необработано консоль:
Это также доступно в узел.js 4.0+, хотя для этого требуется прослушивание специальный unhandledRejection
событие:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
// application specific logging, throwing an error, or other logic here
});
Если вы знакомы с обещания, используйте их. Если нет, вы можете попробовать этот пример, чтобы сделать код более асинхронные :)
function fn1(callback) {
console.log('executing fn1');
callback({status: true});
}
function fn2(callback) {
console.log('executing fn2');
callback({status: false});
}
function test() {
fn1(function(result) {
console.log('fn1 executed with status ' + result.status);
});
fn2(function(result) {
console.log('fn2 executed with status ' + result.status);
if (result.status == false) {
console.log('error in fn2');
}
});
}
test();