ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

错误处理体系

错误处理体系 1.8 错误处理体系错误处理是保障前端交互代码健壮性的核心机制用于捕获和处理程序运行过程中的预期外异常避免代码执行中断导致页面白屏、功能失效。完善的错误处理体系能够精准定位问题、优雅降级用户体验是生产级前端代码的必备组成部分。1.8.1 try/catch/finally 基础语法try/catch/finally 是 JavaScript 最基础的错误捕获语法将可能抛出异常的代码包裹在 try 块中异常发生时自动跳转至 catch 块处理finally 块用于执行无论是否出错都必须执行的收尾逻辑。一、基础语法结构try { // 可能抛出错误的代码 } catch (error) { // 错误发生时执行error 为错误对象 } finally { // 无论是否出错都会执行可选 }二、各块执行规则try 块必填存放待执行的风险代码代码从上到下执行一旦某行抛出错误立即终止后续代码执行跳转至 catch 块catch 块捕获并处理错误参数 error 为错误对象包含错误信息、错误类型、调用栈等信息finally 块可选用于执行收尾操作如关闭连接、清理资源、重置状态无论 try 块正常执行结束还是 catch 捕获到错误finally 都会执行且会在 return 语句之前执行三、基础示例前端最常用的场景安全解析 JSON 字符串避免格式错误导致页面崩溃function parseJSON(str) { try { const data JSON.parse(str); return { success: true, data }; } catch (err) { console.error(JSON 解析失败, err.message); return { success: false, msg: 数据格式错误 }; } finally { console.log(解析操作执行完毕); } } parseJSON({name:张三}); // 正常返回数据 parseJSON({name: 张三}); // 格式错误捕获异常返回失败结果四、错误对象核心属性catch 捕获的 error 对象包含三个核心属性error.message错误描述信息error.name错误类型名称error.stack错误调用栈信息用于定位错误发生位置五、使用注意事项仅用于包裹预期可能出错的代码不要滥用 try/catch 包裹全部代码会掩盖真实问题try/catch 只能捕获同步执行的代码错误异步代码的错误无法直接捕获详见 1.8.3ES2019 后支持省略 catch 的参数即 try {} catch {}但不推荐丢失错误信息不利于问题排查1.8.2 内置错误类型与自定义错误类JavaScript 所有运行时错误都继承自全局 Error 基类内置了多种细分错误类型用于区分不同异常场景开发者也可以通过继承 Error 实现自定义错误类用于业务场景的异常分类与精细化处理。一、常见内置错误类型错误类型触发场景典型示例Error通用错误基类其他错误均继承自它throw new Error(通用异常)SyntaxError语法解析错误代码语法不符合规范JSON.parse({name:1})、书写语法错误ReferenceError引用错误访问了未声明的变量console.log(undefinedVar)TypeError类型错误值的类型不符合操作预期访问 null 的属性、调用非函数值RangeError范围错误数值超出有效取值范围new Array(-1)URIErrorURI 编解码处理错误decodeURI(%)示例按错误类型分类处理try { // 风险代码 } catch (err) { if (err instanceof SyntaxError) { console.log(语法错误, err.message); } else if (err instanceof TypeError) { console.log(类型错误, err.message); } else { console.log(其他错误, err.message); } }二、自定义错误类通过继承 Error 类可以扩展业务属性如错误码、错误等级实现业务异常与系统异常的区分便于统一错误处理逻辑。基础实现业务错误类// 自定义业务错误类 class BusinessError extends Error { constructor(code, message) { super(message); // 调用父类构造函数 this.name BusinessError; // 重写错误名称 this.code code; // 自定义业务错误码 } } // 使用示例 function checkAge(age) { if (typeof age ! number) { throw new TypeError(年龄必须为数字); } if (age 0 || age 150) { throw new BusinessError(1001, 年龄数值不合法); } return true; } // 分层处理错误 try { checkAge(200); } catch (err) { if (err instanceof BusinessError) { console.log(业务异常 [${err.code}]${err.message}); // 业务异常做用户友好提示 } else { console.error(系统异常, err); // 系统异常做日志上报与兜底降级 } }三、自定义错误的工程价值错误分类区分系统异常、业务异常、网络异常对应不同处理策略信息扩展附加错误码、请求 ID、用户信息等字段便于问题排查与日志上报统一处理全局错误拦截时可根据错误类型执行不同的降级与提示逻辑1.8.3 同步与异步错误捕获差异JavaScript 的同步代码与异步代码运行在不同的执行时机导致 try/catch 的捕获能力存在本质差异是前端错误处理最核心的踩坑点。一、同步代码错误同步代码在当前执行栈中运行try/catch 可以直接完整捕获异常发生时立即中断并进入 catch 逻辑。// 可正常捕获 try { JSON.parse(非法json); } catch (err) { console.log(捕获成功, err.message); }二、异步代码错误的常见场景与捕获方式异步代码会脱离当前执行栈待事件循环回调时才执行因此外层的 try/catch 无法捕获到回调内部的错误需要对应异步方案的专属捕获方式。1. 回调函数式异步传统回调写法的错误普遍遵循「错误优先」的约定由回调函数的第一个参数接收错误外层 try/catch 无法捕获。// ❌ 错误写法捕获不到 setTimeout 内部的错误 try { setTimeout(() { throw new Error(异步错误); }, 1000); } catch (err) { console.log(捕获不到, err); } // ✅ 正确写法在回调内部处理错误 setTimeout(() { try { throw new Error(异步错误); } catch (err) { console.log(捕获成功, err.message); } }, 1000);2. Promise 异步Promise 自带错误捕获机制通过 .catch() 方法捕获 rejected 状态的异常是 Promise 规范的标准错误处理方式。// 基础写法链式 catch fetch(/api/data) .then(res res.json()) .then(data console.log(data)) .catch(err { console.error(请求失败, err.message); });注意Promise 内部的同步错误会自动被捕获并转为 rejected 状态不会直接抛出到外层。3. async/await 异步async/await 是 Promise 的语法糖支持使用 try/catch 包裹 await 语句来捕获异步错误写法与同步代码风格一致是当前推荐的异步错误处理方式。async function getData() { try { const res await fetch(/api/data); const data await res.json(); return data; } catch (err) { console.error(请求异常, err.message); // 统一兜底处理 return null; } }三、全局兜底错误捕获对于未被局部捕获的异常可通过全局事件做兜底处理避免页面功能异常同时用于错误日志上报。全局同步错误window.onerrorwindow.onerror function(message, source, lineno, colno, error) { console.error(全局捕获异常, message); // 错误上报逻辑 return true; // 阻止浏览器默认的错误提示 };未处理的 Promise 拒绝unhandledrejectionwindow.addEventListener(unhandledrejection, function(event) { console.error(未捕获的 Promise 异常, event.reason); event.preventDefault(); // 阻止控制台默认报错输出 });四、核心差异总结代码类型主流捕获方式核心原理同步代码try/catch 直接包裹同一执行栈异常同步抛出回调异步回调内部 try/catch/ 错误优先参数回调执行时已脱离外层执行栈Promise.catch () 链式方法Promise 内部自动捕获异常并转为 rejected 状态async/awaittry/catch 包裹 await 语句语法糖本质仍是 Promise 的错误机制
返回列表