编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • README
  • C语言入门精通

  • Cpp入门到精通

  • Java入门精通

  • Go入门到精通

  • JavaScript入门

    • 基础入门

      • README
      • 入门介绍
      • 数据类型
      • 运算符
      • 函数
      • 面向对象
      • 标准库
      • 异步操作
      • 事件设计
      • 错误机制
        • 9.1 错误类型
          • 9.1.1 错误类型说明
          • 9.1.2 Error实例
          • 9.1.3 自定义错误
        • 9.2 throw抛出错误
          • 9.2.1 throw用法
          • 9.2.2 throw建议
        • 9.3 捕获错误
          • 9.3.1 捕获案例
          • 9.3.2 异步捕获
          • 9.3.3 捕获原理
          • 9.3.4 try...catch 的性能影响
        • 9.4 finally
        • 9.5 异步错误处理
          • 9.5.1 Promise错误处理
          • 9.5.2 async/await错误处理
          • 9.5.3 错误处理模式:Result类型
        • 9.6 全局错误处理
          • 9.6.1 window.onerror
          • 9.6.2 unhandledrejection
          • 9.6.3 调试错误
          • 9.6.4 前端错误监控方案
        • 9.7 异常处理流程
          • 9.7.1 未捕获错误处理流程
          • 9.7.2 核心原理
          • 9.7.3 代码示例
          • 9.7.4 处理建议
          • 9.7.5 避免静默失败
      • 模块开发
      • 字符串处理
      • 迭代器与生成器
      • Symbol
      • DOM操作
      • 网络请求
    • 综合案例

    • 专栏博客

  • CodeX
  • JavaScript入门
  • 基础入门
杨充
2025-09-19
目录

错误机制

# 09.错误机制

# 目录介绍

  • 9.1 错误类型
    • 9.1.1 错误类型说明
    • 9.1.2 Error实例
    • 9.1.3 自定义错误
  • 9.2 throw抛出错误
    • 9.2.1 throw用法
    • 9.2.2 throw建议
  • 9.3 捕获错误
    • 9.3.1 捕获案例
    • 9.3.2 异步捕获
    • 9.3.3 捕获原理
  • 9.4 finally
  • 9.5 异步错误处理
    • 9.5.1 Promise错误处理
    • 9.5.2 async/await错误处理
  • 9.6 全局错误处理
    • 9.6.1 window.onerror
    • 9.6.2 unhandledrejection
    • 9.6.3 调试错误
  • 9.7 异常处理流程
    • 9.7.1 未捕获错误处理流程
    • 9.7.2 核心原理
    • 9.7.3 代码示例
    • 9.7.4 处理建议
    • 9.7.5 避免静默失败

# 9.1 错误类型

从ES3开始,JavaScript也提供了类似的异常处理机制,从而让JavaScript代码变的更健壮,即使执行的过程中出现了异常,也可以让程序具有了一部分的异常恢复能力。

JavaScript 异常机制的底层原理:JavaScript 引擎在执行 try 块时,会在调用栈中标记一个异常处理入口点。当 throw 语句执行时,引擎进行栈展开(Stack Unwinding)——从当前执行位置沿调用栈向上查找最近的 try...catch 块。如果找到,则跳转到对应的 catch 块执行;如果整个调用栈都没有 try...catch,错误就变成未捕获异常,触发全局错误处理(window.onerror 或 process.on('uncaughtException'))。注意:try...catch 只能捕获同步代码中的错误,异步回调(如 setTimeout)中的错误需要在回调内部单独捕获,或使用 Promise 的 .catch() / async/await + try...catch。

当错误发生时,JavaScript 提供了错误信息的内置 error 对象。

error 对象提供两个有用的属性:name 和 message 。

# 9.1.1 错误类型说明

JavaScript 中的错误分为以下几种类型:

  1. Error:通用错误类型,其他错误类型都继承自它。
  2. SyntaxError:语法错误,通常在解析代码时发生。
  3. ReferenceError:引用错误,通常发生在访问未定义的变量时。
  4. TypeError:类型错误,通常发生在对错误类型的值进行操作时。
  5. RangeError:范围错误,通常发生在数值超出有效范围时。
  6. URIError:URI 错误,通常发生在处理 URI 时使用无效参数。
  7. EvalError:eval 函数执行错误(已弃用)。

# 9.1.2 Error实例

JavaScript 解析或运行时,一旦发生错误,引擎就会抛出一个错误对象。JavaScript 原生提供Error构造函数,所有抛出的错误都是这个构造函数的实例。

var err = new Error("出错了");
err.message // "出错了"  m
1
2

上面代码中,我们调用Error()构造函数,生成一个实例对象err。Error()构造函数接受一个参数,表示错误提示,可以从实例的message属性读到这个参数。抛出Error实例对象以后,整个程序就中断在发生错误的地方,不再往下执行。

JavaScript 语言标准只提到,Error实例对象必须有message属性,表示出错时的提示信息,没有提到其他属性。大多数 JavaScript 引擎,对Error实例还提供name和stack属性,分别表示错误的名称和错误的堆栈,但它们是非标准的,不是每种实现都有。

  • message:错误提示信息
  • name:错误名称(非标准属性)
  • stack:错误的堆栈(非标准属性)

Error 对象的继承体系:

Error(基类)
  ├── SyntaxError    —— 语法解析错误
  ├── ReferenceError —— 引用不存在的变量
  ├── TypeError      —— 类型使用错误
  ├── RangeError     —— 数值超出范围
  ├── URIError       —— URI 编码/解码错误
  ├── EvalError      —— eval 相关(已弃用)
  └── AggregateError —— 多个错误的集合(ES2021)
1
2
3
4
5
6
7
8

各错误类型的触发场景:

// SyntaxError —— 代码解析阶段就会报错
// eval('var 1abc;'); // SyntaxError: Invalid or unexpected token

// ReferenceError —— 访问未声明的变量
// console.log(undeclaredVar); // ReferenceError

// TypeError —— 对错误类型进行操作
// null.toString(); // TypeError: Cannot read properties of null
// (123)();         // TypeError: 123 is not a function

// RangeError —— 超出范围
// new Array(-1);   // RangeError: Invalid array length
// function f() { f(); } f(); // RangeError: Maximum call stack size exceeded

// URIError —— URI 处理错误
// decodeURIComponent('%'); // URIError

// AggregateError(ES2021)
Promise.any([
  Promise.reject(new Error('err1')),
  Promise.reject(new Error('err2'))
]).catch(e => {
  console.log(e instanceof AggregateError); // true
  console.log(e.errors); // [Error: err1, Error: err2]
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

使用name和message这两个属性,可以对发生什么错误有一个大概的了解。stack属性用来查看错误发生时的堆栈。

function throwit() {
  throw new Error('');
}

function catchit() {
  try {
    throwit();
  } catch(e) {
    console.log(e.stack); // print stack trace
  }
}

catchit()
// Error
//    at throwit (~/examples/throwcatch.js:9:11)
//    at catchit (~/examples/throwcatch.js:3:9)
//    at repl:1:5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

上面代码中,错误堆栈的最内层是throwit函数,然后是catchit函数,最后是函数的运行环境。

# 9.1.3 自定义错误

可以通过继承 Error 类创建自定义错误类型:

class CustomError extends Error {
    constructor(message) {
        super(message);
        this.name = "CustomError";
    }
}

try {
    throw new CustomError("This is a custom error.");
} catch (error) {
    if (error instanceof CustomError) {
        console.error("CustomError:", error.message);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

实际项目中的自定义错误体系:

// 基础业务错误
class AppError extends Error {
  constructor(message, code, statusCode = 500) {
    super(message);
    this.name = 'AppError';
    this.code = code;           // 业务错误码
    this.statusCode = statusCode; // HTTP 状态码
    this.timestamp = new Date().toISOString();
  }
}

// 具体业务错误
class ValidationError extends AppError {
  constructor(field, message) {
    super(message, 'VALIDATION_ERROR', 400);
    this.name = 'ValidationError';
    this.field = field;
  }
}

class AuthenticationError extends AppError {
  constructor(message = '未授权访问') {
    super(message, 'AUTH_ERROR', 401);
    this.name = 'AuthenticationError';
  }
}

class NotFoundError extends AppError {
  constructor(resource) {
    super(`${resource} 不存在`, 'NOT_FOUND', 404);
    this.name = 'NotFoundError';
    this.resource = resource;
  }
}

// 使用
function getUser(id) {
  if (!id) throw new ValidationError('id', 'ID 不能为空');
  const user = db.find(id);
  if (!user) throw new NotFoundError('User');
  return user;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

# 9.2 throw抛出错误

# 9.2.1 throw用法

使用 throw 关键字抛出错误。

function divide(a, b) {
  if (b === 0) {
    throw new Error("Division by zero is not allowed!");
  }
  return a / b;
}

console.log(divide(10, 0)); // 抛出错误
1
2
3
4
5
6
7
8

实际上,throw可以抛出任何类型的值。也就是说,它的参数可以是任何值。

// 抛出一个字符串
throw 'Error!';
// Uncaught Error!

// 抛出一个数值
throw 42;
// Uncaught 42

// 抛出一个布尔值
throw true;
// Uncaught true

// 抛出一个对象
throw {
  toString: function () {
    return 'Error!';
  }
};
// Uncaught {toString: ƒ}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

对于 JavaScript 引擎来说,遇到throw语句,程序就中止了。引擎会接收到throw抛出的信息,可能是一个错误实例,也可能是其他类型的值。

# 9.2.2 throw建议

  1. 错误类型:尽量抛出 Error 对象或其子类,而不是字符串或其他类型。
  2. 错误信息:错误信息应清晰明确,便于调试。
  3. 异常处理:使用 try...catch 捕获和处理错误,避免程序崩溃。

# 9.3 捕获错误

try...catch 是 JavaScript 中最常用的错误处理机制,用于捕获同步代码中的异常。

语法

try {
    // 可能抛出错误的代码
} catch (error) {
    // 捕获并处理错误
} finally {
    // 无论是否发生错误,都会执行的代码
}
1
2
3
4
5
6
7

# 9.3.1 捕获案例

示例

try {
    let result = riskyOperation();
    console.log("Result:", result);
} catch (error) {
    console.error("An error occurred:", error.message);
} finally {
    console.log("Execution completed.");
}
1
2
3
4
5
6
7
8

特点

  • try 块中的代码会被执行,如果抛出错误,则进入 catch 块。
  • catch 块中的 error 参数是一个错误对象,通常包含 message 和 name 属性。
  • finally 块中的代码无论是否发生错误都会执行,通常用于清理资源。

# 9.3.2 异步捕获

在异步代码(如 Promise 或 async/await)中,异常捕获的方式略有不同。

async function fetchData() {
  try {
    let response = await fetch("https://example.com/data");
    let data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("捕获到错误:", error.message);
  }
}

fetchData();
1
2
3
4
5
6
7
8
9
10
11

# 9.3.3 捕获原理

如果 try 块中的代码正常执行,catch 块会被跳过。

如果 try 块中的代码抛出错误,程序会立即跳转到 catch 块,并执行其中的代码。

无论是否发生错误,finally 块中的代码都会执行。

# 9.3.4 try...catch 的性能影响

疑惑:使用 try...catch 会影响性能吗?

答疑:在现代 V8 引擎中,try...catch 本身的性能开销已经非常小。但需要注意几点:

论证:

// 以前(旧版 V8):try...catch 内的代码无法被 JIT 优化
// 现在(V8 TurboFan):try...catch 内的代码可以正常优化

// 但是,不建议将整个函数体包裹在 try...catch 中
// 不推荐
function processAll(data) {
  try {
    // 200 行代码...
  } catch (e) {
    handleError(e);
  }
}

// 推荐:只包裹可能出错的代码
function processAll(data) {
  const validated = validate(data); // 不需要 try...catch
  
  try {
    const result = riskyOperation(validated);
  } catch (e) {
    handleError(e);
  }
  
  cleanup(); // 确定不会出错的代码
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

结果展示:合理使用 try...catch,将其范围缩小到可能出错的代码段。过大的 try 块会降低代码可读性,也不利于精确定位错误。

# 9.4 finally

try...catch结构允许在最后添加一个finally代码块,表示不管是否出现错误,都必需在最后运行的语句。无论是否发生错误都会执行,通常用于清理资源。

function cleansUp() {
  try {
    throw new Error('出错了……');
    console.log('此行不会执行');
  } finally {
    console.log('完成清理工作');
  }
}

cleansUp()
// 完成清理工作
// Uncaught Error: 出错了……
//    at cleansUp (<anonymous>:3:11)
//    at <anonymous>:10:1
1
2
3
4
5
6
7
8
9
10
11
12
13
14

上面代码中,由于没有catch语句块,一旦发生错误,代码就会中断执行。中断执行之前,会先执行finally代码块,然后再向用户提示报错信息。

function idle(x) {
  try {
    console.log(x);
    return 'result';
  } finally {
    console.log('FINALLY');
  }
}

idle('hello')
// hello
// FINALLY
1
2
3
4
5
6
7
8
9
10
11
12

finally 的特殊行为:

// finally 中的 return 会覆盖 try/catch 中的 return
function foo() {
  try {
    return 1;
  } catch (e) {
    return 2;
  } finally {
    return 3; // 这个 return 会覆盖上面的所有 return
  }
}
console.log(foo()); // 3

// finally 中的 return 甚至会"吞掉"错误
function bar() {
  try {
    throw new Error('错误');
  } finally {
    return '正常'; // 错误被吞掉,不会抛出
  }
}
console.log(bar()); // "正常"(错误消失了!)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

最佳实践:永远不要在 finally 中使用 return,它会导致难以追踪的 bug。

# 9.5 异步错误处理

# 9.5.1 Promise错误处理

使用 .catch() 捕获 Promise 中的错误。

fetch("https://example.com/data")
  .then((response) => response.json())
  .catch((error) => {
    console.error("Fetch error:", error);
  });
1
2
3
4
5

# 9.5.2 async/await错误处理

使用 try...catch 捕获 async/await 中的错误。

async function fetchData() {
  try {
    const response = await fetch("https://example.com/data");
    const data = await response.json();
    console.log(data);
  } catch (error) {
    console.error("Fetch error:", error);
  }
}

fetchData();
1
2
3
4
5
6
7
8
9
10
11

# 9.5.3 错误处理模式:Result类型

疑惑:每次调用异步函数都要写 try...catch,代码很冗长。有没有更优雅的方式?

答疑:可以借鉴 Go/Rust 语言的"返回错误而非抛出错误"模式,将 try...catch 封装为工具函数:

论证:

// 工具函数:将 async 函数的错误转为返回值
async function to(promise) {
  try {
    const result = await promise;
    return [null, result];
  } catch (error) {
    return [error, null];
  }
}

// 使用
async function fetchUserData(userId) {
  const [err, response] = await to(fetch(`/api/users/${userId}`));
  if (err) {
    console.error('网络错误:', err);
    return null;
  }
  
  const [parseErr, data] = await to(response.json());
  if (parseErr) {
    console.error('解析错误:', parseErr);
    return null;
  }
  
  return data;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

结果展示:这种模式消除了深层嵌套的 try...catch,使错误处理更加线性和明确。许多 Node.js 库(如 await-to-js)都提供了类似的工具。

# 9.6 全局错误处理

# 9.6.1 window.onerror

捕获全局未处理的错误。

window.onerror = function (message, source, lineno, colno, error) {
  console.error("Global error:", message, "at", source, "line", lineno);
  return true; // 阻止默认错误提示
};
1
2
3
4

# 9.6.2 unhandledrejection

捕获未处理的 Promise 拒绝。

window.addEventListener("unhandledrejection", function (event) {
  console.error("Unhandled rejection:", event.reason);
});
1
2
3

# 9.6.3 调试错误

  • console.error():打印错误信息。
  • console.trace():打印调用堆栈。
  • 开发者工具:使用浏览器的开发者工具调试错误。

# 9.6.4 前端错误监控方案

在生产环境中,需要一套完整的错误监控体系来收集和上报错误:

// 统一的错误监控类
class ErrorMonitor {
  constructor(reportUrl) {
    this.reportUrl = reportUrl;
    this.init();
  }
  
  init() {
    // 1. 捕获同步错误
    window.onerror = (message, source, lineno, colno, error) => {
      this.report({
        type: 'javascript',
        message, source, lineno, colno,
        stack: error?.stack
      });
      return false; // 不阻止默认处理
    };
    
    // 2. 捕获 Promise 未处理的拒绝
    window.addEventListener('unhandledrejection', (event) => {
      this.report({
        type: 'promise',
        message: event.reason?.message || String(event.reason),
        stack: event.reason?.stack
      });
    });
    
    // 3. 捕获资源加载错误(window.onerror 无法捕获)
    window.addEventListener('error', (event) => {
      if (event.target !== window) {
        this.report({
          type: 'resource',
          tagName: event.target.tagName,
          src: event.target.src || event.target.href
        });
      }
    }, true); // 必须在捕获阶段
  }
  
  report(errorInfo) {
    const data = {
      ...errorInfo,
      url: location.href,
      userAgent: navigator.userAgent,
      timestamp: Date.now()
    };
    
    // 使用 navigator.sendBeacon 保证页面卸载时也能发送
    navigator.sendBeacon(this.reportUrl, JSON.stringify(data));
  }
}

// 初始化
new ErrorMonitor('/api/errors/report');
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

# 9.7 异常处理流程

在 JavaScript 中,未捕获的错误(Uncaught Error) 是指没有被 try...catch 语句捕获的异常。

这类错误会触发 JavaScript 引擎的默认错误处理机制,通常会导致程序终止并打印错误信息。

# 9.7.1 未捕获错误处理流程

(1)错误抛出:当代码中发生错误(如 throw new Error("Something went wrong"))且没有被 try...catch 捕获时,错误会被抛出。

(2)错误传播:错误会沿着调用栈向上传播,直到找到最近的 try...catch 块。如果调用栈中没有 try...catch 块,错误会继续传播到全局作用域。

(3)全局错误处理:如果错误传播到全局作用域,JavaScript 引擎会触发全局错误处理机制:

  • 在浏览器中,会触发 window.onerror 事件。
  • 在 Node.js 中,会触发 process.on('uncaughtException') 事件。

(4)程序终止:如果全局错误处理机制也没有捕获错误,JavaScript 引擎会终止程序的执行,并打印错误信息到控制台。

# 9.7.2 核心原理

(1)调用栈(Call Stack):JavaScript 使用调用栈来管理函数的执行顺序。当发生错误时,引擎会沿着调用栈向上查找是否有 try...catch 块来处理错误。

(2)事件循环(Event Loop):在异步代码中,错误可能发生在事件循环的不同阶段。如果错误未被捕获,它会被传递到全局作用域。

(3)全局错误事件:JavaScript 提供了全局错误事件来捕获未处理的错误:

  • 浏览器:window.onerror 和 window.addEventListener('error', ...)。
  • Node.js:process.on('uncaughtException') 和 process.on('unhandledRejection')。

# 9.7.3 代码示例

(1)同步代码中的未捕获错误

function foo() {
    throw new Error("Oops!");
}

function bar() {
    foo();
}

bar(); // 未捕获错误,程序终止
1
2
3
4
5
6
7
8
9

(2)异步代码中的未捕获错误

setTimeout(() => {
    throw new Error("Oops!");
}, 1000); // 未捕获错误,程序终止
1
2
3

(3)全局错误处理(浏览器)

window.onerror = function (message, source, lineno, colno, error) {
    console.log("捕获到全局错误:", message);
    return true; // 阻止默认错误处理
};

throw new Error("Oops!"); // 错误被全局处理,程序不会终止
1
2
3
4
5
6

(4)全局错误处理(Node.js)

process.on('uncaughtException', (err) => {
    console.log("捕获到未处理的异常:", err.message);
});

throw new Error("Oops!"); // 错误被全局处理,程序不会终止
1
2
3
4
5

# 9.7.4 处理建议

(1)使用 try...catch:在可能抛出错误的代码块中使用 try...catch 捕获错误。

try {
    throw new Error("Oops!");
} catch (error) {
    console.log("捕获到错误:", error.message);
}
1
2
3
4
5

(2)全局错误处理:在全局作用域中注册错误处理函数,捕获未处理的错误。

// 浏览器
window.addEventListener('error', (event) => {
    console.log("捕获到全局错误:", event.message);
});

// Node.js
process.on('uncaughtException', (err) => {
    console.log("捕获到未处理的异常:", err.message);
});
1
2
3
4
5
6
7
8
9

3)Promise 错误处理:使用 .catch() 或 try...catch(在 async/await 中)捕获 Promise 中的错误。

// 使用 .catch()
Promise.reject(new Error("Oops!")).catch((error) => {
    console.log("捕获到 Promise 错误:", error.message);
});

// 使用 async/await
(async () => {
    try {
        await Promise.reject(new Error("Oops!"));
    } catch (error) {
        console.log("捕获到错误:", error.message);
    }
})();
1
2
3
4
5
6
7
8
9
10
11
12
13

4)避免静默失败:确保所有错误都被捕获和处理,避免程序静默失败。

# 9.7.5 避免静默失败

阶段 描述
错误抛出 代码中发生错误且未被捕获。
错误传播 错误沿着调用栈向上传播,寻找 try...catch 块。
全局错误处理 如果错误未被捕获,触发全局错误事件(如 window.onerror)。
程序终止 如果全局错误处理也未捕获错误,程序终止并打印错误信息。
上次更新: 2026/06/10, 11:13:41
事件设计
模块开发

← 事件设计 模块开发→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式