错误处理try catch
捕获异步
setTimeout(() => {
try{
// do some
} catch (err) {
// 这里捕获
}
}, 1000)
抛出自定义错误throw
let json = '{ "age": 30 }'; // 不完整的数据
try {
let user = JSON.parse(json); // <-- 没有 error
if (!user.name) {
throw new SyntaxError("Incomplete data: no name"); // (*)
}
alert( user.name );
} catch(e) {
alert( "JSON Error: " + e.message ); // JSON Error: Incomplete data: no name
}
再次抛出
预料之外的错误,catch中不止如处理,则可以再次抛出。
此时,更外层的 try catch
将捕获到错误,但如果外部不存在这种结构,脚本就会被杀死。
try catch finally
* finally和return
控制转向外部之前 finally
先执行
function func() {
try {
return 1;
} catch (e) {
//...
} finally {
alert('finally')
}
}
alert(func()); // 先执行finally中的alert,再执行alert 1
全局catch
window.onerror = function(message, url, line, col, error) {}
// node
process.on("uncaughtException")
自定义Error
扩展自Error
Error类的内部实现大致是:
class Error {
constructor(message) {
this.message = message
this.name = 'Error' // 不同Error类,比如SyntaxError就是this.name = 'SyntaxError'
this.stack = <call stack> // 调用栈信息
}
}
所以我们可以继承,重写name。
class MyError extends Error {
constructor(message) {
super(message)
this.name = 'MyError'
}
}
const myErr = new MyError('我的自定义错误')
myErr.name = 'MyError'
通过 intanceof
操作符,可以判断错误是否是你的自定义错误,从而来做特殊的处理。如果不确定的错误,则应再次抛出。
if(err instanceof MyError) {
// ... do some
} else {
// 再次抛出,在try catch里说过。
throw err
}
深入继承
这里举个例子,访问对象的某个属性的错误处理。
class ValidationError extends Error {
constructor(msg) {
super(msg)
this.name = 'validationError'
}
}
class PropertyRequiredError extends ValidatationError {
constructor(property) {
// 使用方便,只需要new PropertyRequiredError('属性名')即可,报错message由super,也就是Error的constructor函数来做this.message = message
super('no property: ' + property)
this.name = 'PropertyRequiredError'
}
}
// read some json
if(!user.name) {
throw new PropertyRequiredError('name')
}
我们在每个自定义的Error类中都重写了name,这步可以简写为
// 一个自定义的Error父类,其他自定义Error类继承自该父类。
// 因为我们无法重写Error内建类
class MyError extends Error {
constructor(msg) {
super(msg)
// 使用当前调用构造函数名
this.name = this.constructor.name
}
}
class ValidationError extends MyError {}
new ValidationError() // this.name = ValidationError