try...catch 基础用法

  1. function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. try {
  5. thisThrows();
  6. } catch (e) {
  7. console.error(e);
  8. } finally {
  9. console.log("We do cleanup here");
  10. }
  11. // Output:
  12. // Error: Thrown from thisThrows()
  13. // ...stacktrace <-- 这里是错误堆栈,用于查看调用栈(下文同)
  14. // We do cleanup here

捕获 Promise 错误

Case #1: try...catch 捕获

  1. async function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. async function run() {
  5. try {
  6. await thisThrows(); // <-- await 这个 Promise
  7. } catch (e) {
  8. console.error(e);
  9. } finally {
  10. console.log("We do cleanup here");
  11. }
  12. }
  13. run();
  14. // Output:
  15. // Error: Thrown from thisThrows()
  16. // ...stacktrace
  17. // We do cleanup here

Case #2: .catch() 捕获

  1. async function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. thisThrows()
  5. .catch(console.error)
  6. .then(() => console.log("We do cleanup here"));
  7. // Output:
  8. // Error: Thrown from thisThrows()
  9. // ...stacktrace
  10. // We do cleanup here

捕获嵌套 Promise 错误

  1. async function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. async function myFunctionThatCatches() {
  5. try {
  6. // 使用 `await` 捕获嵌套函数中的第一个错误
  7. return await thisThrows();
  8. } catch (e) {
  9. console.error(e);
  10. } finally {
  11. console.log("We do cleanup here");
  12. }
  13. return "Nothing found";
  14. }
  15. async function run() {
  16. const myValue = await myFunctionThatCatches();
  17. console.log(myValue);
  18. }
  19. run();
  20. // Outptut:
  21. // Error: Thrown from thisThrows()
  22. // ...stacktrace
  23. // We do cleanup here
  24. // Nothing found

重置错误堆栈

堆栈丢失问题

  1. function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. function myFunctionThatCatches() {
  5. try {
  6. return thisThrows();
  7. } catch (e) {
  8. throw new TypeError(e.message);
  9. } finally {
  10. console.log("We do cleanup here");
  11. }
  12. }
  13. async function run() {
  14. try {
  15. await myFunctionThatCatches();
  16. } catch (e) {
  17. console.error(e);
  18. }
  19. }
  20. run();
  21. // Outputs:
  22. // We do cleanup here
  23. // TypeError: Error: Thrown from thisThrows()
  24. // at myFunctionThatCatches (/repo/error_stacktrace_1.js:9:15) <-- 错误指向 `try catch` 块
  25. // at run (/repo/error_stacktrace_1.js:17:15)
  26. // at Object.<anonymous> (/repo/error_stacktrace_1.js:23:1)

⚠️第28行,错误显示仅捕获到了 myFunctionThatCatches 块的错误。

如何解决

  1. function thisThrows() {
  2. throw new Error("Thrown from thisThrows()");
  3. }
  4. function myFunctionThatCatches() {
  5. try {
  6. return thisThrows();
  7. } catch (e) {
  8. // !! 也许先在这里做其他事情
  9. throw e;
  10. } finally {
  11. console.log("We do cleanup here");
  12. }
  13. }
  14. async function run() {
  15. try {
  16. await myFunctionThatCatches();
  17. } catch (e) {
  18. console.error(e);
  19. }
  20. }
  21. run();
  22. // Outputs:
  23. // We do cleanup here
  24. // Error: Thrown from thisThrows()
  25. // at thisThrows (/repo/error_stacktrace_2.js:2:11) <-- 注意,我们现在指向实际错误的来源
  26. // at myFunctionThatCatches (/repo/error_stacktrace_2.js:7:16)
  27. // at run (/repo/error_stacktrace_2.js:18:15)
  28. // at Object.<anonymous> (/repo/error_stacktrace_2.js:24:1)

⚠️29 行捕获到了嵌套在 myFunctionThatCatches 内部的错误 thisThrows

运行环境

报错:ReferenceError: regeneratorRuntime is not defined
原因:async/await 需要配置运行环境
解决:

  1. npm i regenerator-runtime -D
  1. // 入口文件
  2. import "regenerator-runtime/runtime.js";