📕
余烬的小册
数据结构与算法GitHub
  • 总述
  • 经验记录
    • 经验总结
      • web component
      • 前端性能优化总结与分析
      • 我的长列表优化方案
      • 双向通讯解决方案
      • 🔧基于istanbul实现代码测试覆盖率工具
      • 表单系统(低代码表单)
      • 跨端小程序
      • 设计一个即时聊天功能
      • 跨页面通讯 3658699fe4cb4d0bbe22b0881390bacd
    • 踩坑记录
      • HTML踩坑记录
      • Flutter踩坑记录
      • CSS踩坑记录
  • 源码解析
    • Vue源码解析
      • Vue2源码解析系列-响应式原理
      • Vue2源码解析系列-模板编译
      • Vue2源码解析系列-渲染系统(待更新)
        • Patch
      • Vue2源码解析系列-调度系统(todo)
      • Vue2组件更新流程(todo)
      • 如何学习Vue源码
      • Vue3源码解析系列-响应系统
      • Vue3源码解析系列-渲染系统
      • Vue3源码解析系列-组件化和渲染优化(todo)
      • Vue router源码解析(todo)
    • React源码解析(todo)
    • 微前端
      • qiankun源码解析(todo)
    • Vite源码解析
      • Vite Client源码
      • Vite Server源码(todo)
  • 前端技术
    • javaScript
      • ES6
        • 变量声明
        • 模块化
        • 箭头函数
        • 你不知道的for...of
        • 新的数据结构Set和Map
        • JavaScript异步编程终极解决方案
        • ES6 Class 3a0c0a225a534984aabe9a943c5df975
      • JavaScript Error
      • JavaScript浅拷贝和深拷贝
      • JavaScript闭包
      • JavaScript最佳实践
      • JavaScript设计模式
      • async函数的polyfill
    • 深入理解JavaScript系列
      • JavaScript中的继承
      • JavaScript原始类型和引用类型
      • JavaScript浅拷贝和深拷贝
      • JavaScript手写系列
      • JavaScript之this
      • 词法环境和环境记录
      • JavaScript内存泄漏
      • 执行上下文
      • 从ECMAScript规范中学习this
    • TypeScript
      • TypeScript基础教程
      • Typescript高级操作
      • TypeScript工具类型
      • Typescript手写实现工具类型
      • Typescript总结(思维导图)
    • 浏览器原理
      • 页面渲染原理
      • 浏览器存储
      • JavaScript事件循环
      • 事件循环
      • 跨域
      • DOM事件流
      • 从输入url到页面渲染
      • 判断节点之间的关系及根据节点关系查找节点
      • history API
    • 跨端技术
      • Flutter
        • Flutter布局组件
    • 前端工程化
      • Babel插件开发指南
      • 循环依赖
      • pm2
    • React
      • React 状态管理
      • React组件通讯
      • Redux入门
      • Flux
      • React Hook(todo)
      • Effect
  • 服务器端
    • 计算机网络
      • 应用层
      • 运输层
      • 物理层
      • 数据链路层
      • HTTP缓存
      • HTTPS
      • 网络层
    • NodeJs
      • Node.js
      • nodejs最佳实践
      • 《深入浅出Nodejs》小结
      • mongoose填充(populate)
      • node事件循环
      • Node子进程
      • nestjs从零开始
      • nodejs流
      • Nodejs调试
      • Koa源码解析
    • 服务器
      • 操作系统
      • Linux
      • nginx常用指令
      • nginx常用配置
    • 数据库
      • Mysql常见语法
      • MongoDB Indexes索引
  • 前端安全与性能优化
    • 前端安全
      • 跨站脚本攻击(XSS)
      • 跨站点请求伪造(CSRF)
      • 点击劫持
      • 中间人攻击
      • 越权攻击与JWT
    • 前端性能优化
      • 前端监控系统
      • 前端性能优化总结与分析 7348bba0918645b1899006dc842a64c1
      • 衡量性能的核心指标 0dc15ef127cf4f4a9f1137c377420292
      • 图片懒加载
  • 杂项
    • 其他
      • Git
      • web component框架
      • 实现滚动框的懒加载
      • Stencil指南
    • CSS
      • 定位和层叠上下文
      • BFC
      • 盒模型
      • css选择器
      • css变量
由 GitBook 提供支持
在本页
  • Error类型
  • Error类型
  • 识别Error类型
  • 抛出错误
  • 自定义Error类型
  • 捕获异常
  • try…catch…finally
  • window.onerror
  • 新特性
  • Error Cause
  • 参考
在GitHub上编辑
  1. 前端技术
  2. javaScript

JavaScript Error

Error类型

Error类型

ECMAScript定义了几种错误类型:

  • Error : 所有错误类型的基类,其他错误类型都继承该类型。

  • [EvalError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/EvalError) : 创建一个 error 实例,表示错误的原因:与 [eval()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval) 有关。

  • [RangeError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/RangeError) :创建一个 error 实例,表示错误的原因:数值变量或参数超出其有效范围。

  • [ReferenceError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/ReferenceError) :创建一个 error 实例,表示错误的原因:无效引用。

  • [SyntaxError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/SyntaxError) :创建一个 error 实例,表示错误的原因:语法错误。

  • [TypeError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/TypeError) :创建一个 error 实例,表示错误的原因:变量或参数不属于有效类型。

  • [URIError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/URIError) :创建一个 error 实例,表示错误的原因:给 [encodeURI()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/encodeURI) 或 [decodeURI()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/decodeURI) 传递的参数无效。

  • [AggregateError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/AggregateError) : 创建一个 error 实例,其中包裹了由一个操作产生且需要报告的多个错误。如:[Promise.any()](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/any) 产生的错误。

  • [InternalError](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/InternalError) 非标准: 创建一个代表 Javascript 引擎内部错误的异常抛出的实例。如:递归太多。

识别Error类型

不同的错误类型可用于为异常提供更多信息,以便实现适当的错误处理逻辑,如果你需要识别错误类型,可以在catch块中通过instanceof来判断error对象的类型。

try{ 
	const a = 1;
	a = 2;
}catch(error){
	console.log(error instanceof TypeError);
	// true
}

抛出错误

抛出错误需要用到throw操作符,它可以抛出任何值,并且js一旦执行throw语句,就会立即停止执行,除非try…catch语句捕捉了抛出的异常。

// throw抛出的值类型不限
throw 1
throw '1'
throw {a: 1}
throw true

但是通常我们最好抛出一个错误对象来模拟浏览器错误,抛出一个错误对象比直接抛出一个值(例如字符串)更好的地方在于前者会包含调用栈等信息,以便后续修复异常。

(function(){
	let a = 123; 
	throw new Error(123)  
})()

/*
VM2736:1 Uncaught Error: 123
    at <anonymous>:1:32
    at <anonymous>:1:50
(匿名) @ VM2736:1
(匿名) @ VM2736:1
*/

抛出一个错误对象很简单,只需要通过实例化一个内置错误类即可,通常是Error,因为其他的错误类都是继承于Error,你只需要传递一个参数message,即错误消息。message是可选的,但是通常我们都会传,以便更好地处理错误。

function sort(arr){
	if(!Array.isArray(arr)){ 
		throw new Error('参数类型错误,你应当传递一个数组类型')
	}
	return arr.sort((a,b)=> a-b);
}
sort(1);
// Uncaught Error: 参数类型错误,你应当传递一个数组类型

当然你也可以抛出一个具体的错误对象,例如上面这里例子中使用TypeError可以更好地表示是类型错误。

throw new TypeError('你应当传递一个数组类型')
// Uncaught TypeError: 你应当传递一个数组类型

除了Error和其他内置错误对象,你还可以自定义Error类型。

自定义Error类型

创建一个自定义Error类型很简单,只需要实现一个继承Error的类,并实现message属性和name属性即可。

class CustomError extends Error {
  constructor(name='CustomError ', message) {
    super();

    this.name = name;
    this.message = message;
  }
}

示例:

下面这个实例中实现了一个自定义Error类型CustomError,在输入框中输入CustomError.name和CustomError.message后点击抛出异常按钮,你应当可以在控制台看到错误信息。

捕获异常

try…catch…finally

try…catch可以捕获异常,当try块中发生错误时,代码会立即退出执行,并跳到catch块中执行,catch块此时会接收到一个错误对象,该错误对象包含错误的相关信息,这个错误对象中的信息根据浏览器而异,但是它至少会包含message属性。

try{
	const a = 1;
	a++; // 产生一个错误
	console.log(1)  // 不会执行
}catch(err){ 
	// 错误对象是必须要声明的,即使你不用它
}

finally块是可选的,无论是否发生错误,finally块的代码都会执行,并且try或catch块都无法阻止finally块的执行。

function fn(){ 
	try{
		return 1;
	}catch(err){
		return 2;
	}finally{ 
		console.log(3)
	}
}

fn() // 3

window.onerror

任何没有被try…catch捕获的异常都会传递到window.onerror事件上,在onerror事件处理程序上通常有这么几个参数:

  1. 错误消息message

  2. 错误文档的URL

  3. 错误发生的行号

  4. 错误发送的列号

  5. 错误对象

如果window.onerrror事件处理程序中返回为true,那么控制台将不会打印错误信息,即:

window.onerror = function (message, url, lno, cno, error) {
    console.table({
        message,
        url,
        lno,
        cno,
        error
    });
    return true;
}

window.onerror是处理错误的最后一道防线,可以在此将异常上报,以便后续追踪修复。

新特性

Error Cause

Error Cause当前已经到达第四阶段,Error Cause的作用是在从深层内部逻辑引发的错误时,能够将错误对象一同抛出,以此来增强错误描述。

可以看下这个例子:

// 私有函数
function _sort(arr) {
    return arr.sort((a, b) => a - b)
}

export function sort(arr) {
    // ... 处理某些逻辑
    try {
        _sort(arr)
    } catch (err) {
        throw new Error('执行sort错误,原因是'+ err.message)
    }
}

sort(1)
// Uncaught Error: 执行sort错误,原因是arr.sort is not a function

在这个例子中,我们提前预见_sort函数的执行可能会出现异常,因此我们用try…catch捕获异常,但是我们并不能提前预判是哪种异常,因此我们只能提示有错误,并将错误消息(即err.message)一同显示。但是这种并不是很友好,因为err错误对象只有错误消息被传递,由于错误是深层的,错误堆栈不会追踪到_sort函数,除非我们去_sort函数源码,否则我们很难判断错误发送的原因,但是Error Cause能够将错误对象一同携带出来,我们可以通过错误对象的错误堆栈来快速地追踪到错误。

使用error cause很简单,只需要在Error实例化时第二个参数传递一个包含cause属性的对象,而cause属性的值就是错误对象。

function _sort(arr) {
    return arr.sort((a, b) => a - b)
}

function sort(arr) {
    // ... 处理某些逻辑
    try {
        _sort(arr)
    } catch (err) {
        throw new Error('执行sort错误', {
            cause: err
        })
    }
}

sort(1)
Uncaught Error: 执行sort错误
    sort http://127.0.0.1:5500/error.html:75
    <anonymous> http://127.0.0.1:5500/error.html:81
Caused by: TypeError: arr.sort is not a function
    _sort http://127.0.0.1:5500/error.html:67
    sort http://127.0.0.1:5500/error.html:73
    <anonymous> http://127.0.0.1:5500/error.html:81

当使用Error Cause后,_sort函数错误堆栈也能被打印出来,可以很快的锁定错误。

参考

《JavaScript高级程序设计第四版》

上一页ES6 Class 3a0c0a225a534984aabe9a943c5df975下一页JavaScript浅拷贝和深拷贝

最后更新于1年前

更多信息见:

https://codesandbox.io/s/zi-ding-yi-cuo-wu-lei-xing-nj0c9g
前端监控方案
Window: error event - Web API 接口参考 | MDN (mozilla.org)
Error - JavaScript | MDN (mozilla.org)
Error() constructor - JavaScript | MDN (mozilla.org)
https://github.com/tc39/proposal-error-cause