Нужно ли включать try...catch
во все функции?
Нет, не нужно, если только вы по какой-то причине не хотите регистрировать его на каждом уровне. Просто обработайте это на верхнем уровне.
В функции async
отклонения обещаний являются исключениями (как вы знаете, поскольку вы используете с ними try
/ catch
), а исключения распространяются через дерево вызовов async
до тех пор, пока они не будут пойманы. Скрытые функции async
возвращают обещания и отклоняют эти обещания, когда возникает синхронное исключение или когда обещание async
функция await
отклоняет.
Вот простой пример:
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function outer() {
// ...
await delay(10);
console.log("before calling inner");
await inner();
console.log("after calling inner (we never get here)");
}
async function inner() {
// ...
await delay(10);
console.log("inside inner");
// Something goes wrong
null.foo();
}
outer()
.catch(e => {
console.log("Caught error: " + e.message, e.stack);
});
В качестве побочного примечания: если вы сделаете поймаете ошибку, потому что вы хотите выполнить X до того, как ошибка распространится, и вы собираетесь повторно выбросить ошибку после того, как вы сделаете X, лучше всего повторно выбросить ошибку, которую вы поймали, а не создавать новую. Итак:
} catch (e) {
// ...do X...
throw e; // <== Not `throw new Error(e);`
}
Но делайте это только в том случае, если вам действительно нужно выполнить X при возникновении ошибки. В большинстве случаев просто полностью отключите try
/ catch
.