Node.js程序异常处理
使用throw关键字抛出异常
throw
关键字用于抛出一个异常,它可以在特定的情形下自行抛出异常。throw
语句的基本格式如下:
throw value
参数 value
表示抛出的异常,它的值可以是任何 JavaScript 类型的值(包括字符串、数字或对象等)。例如,在 JavaScript 代码中使用下面代码抛出不同类型的异常都是合法的:
throw "程序出错了"; //抛出了一个值为字符串的异常
throw 1; //抛出了一个值为整数1的异常
throw true; //抛出了一个值为true的异常
但在 Node.js 中,通常不抛出这些类型的值,而是抛出 Error
对象,例如下面的代码:
throw new Error('程序出错了')
Error错误对象
上面讲到,在 Node.js 中通常使用 throw
抛出 Error
对象,那么 Error
对象是什么呢?
Error
对象是一个错误对象,它由 Error
核心模块提供,当使用 Error
对象时,并不表明错误发生的具体情况,它会捕获堆栈跟踪,并提供所发生错误的描述内容。Error
对象的使用方法如下:
new Error(message)
参数 message
表示要显示的错误信息。
Error
对象提供了一些属性,用于获取错误相关的信息,分别如下。
-
name
属性:获取错误的类型名称,比如内置错误类型TypeError
等。 -
message
属性:获取错误信息。 -
stack
属性:获取代码中Error
被实例化的位置。
Error
类是 Node.js
中所有错误类的基类,其常用子类及说明如表 17.1 所示。

例如,下面代码定义了一个代码块,其中通过实例化 Error
对象创建了一个异常,并使用 throw
关键字抛出该异常:
let syncError = () => {
throw new Error('自定义异常')
}
使用try…catch语句捕获异常
异常定义之后,需要在程序中捕获,这时需要使用 try…catch
语句。try…catch
语句允许在 try
后面的大括号 {}
中放置可能发生异常情况的程序代码,以对这些代码进行监控;在 catch
后面的大括号 {}
中放置处理异常的程序代码。try…catch
语句的基本语法如下:
try {
//可能会出错的代码,出错时抛出一个错误
} catch (e) {
//处理异常的代码
}
参数 e
表示捕获的异常。
例如,下面代码使用 try…catch
捕获 17.3.2 节示例代码中抛出的异常信息:
try {
syncError()
} catch (e) {
console.log(e.message)
}
console.log('异常被捕获')
程序运行如下:
自定义异常
异常被捕获
在开发程序时,如果遇到需要处理多种异常信息的情况,可以在一个 |
完整的异常处理语句应该包含 finally
代码块,通常情况下,无论程序中有无异常产生,finally
代码块中的代码都会被执行,其语法格式如下:
try{
//可能会出错的代码,出错时抛出一个错误
}catch(e){
//处理异常的代码
}finally{
//最终执行的代码
}
使用 try…catch…finally
语句时,不管 try
代码块内有没有抛出异常,finally
代码块总会被执行。如果 try
代码块内发生错误,finally
代码块将在 catch
代码块之后被执行;如果没有发生错误,将跳过 catch
代码块,直接执行 finally
代码块中的代码。
使用异常处理语句时,可以不写
运行结果如下:
|
异步程序中的异常处理
前面讲解的是同步程序的异常捕获,如果是异步程序出现异常,该如何捕获呢?例如,下面是一个异步代码块,其中抛出了一个异常,代码如下:
//模拟异步代码块内出现异常
let asyncError = () => {
setTimeout(function () {
throw new Error('异步异常')
}, 100)
}
如果我们使用传统的 try…catch
捕获上面异步代码中抛出的异常,则写法应该如下:
(async function () {
try {
await asyncError()
} catch (e) {
console.log(e.message) //处理异常
}
})()
但在运行程序时,却出现了如图 17.12 所示的结果。

通过上面示例代码可以看出,异步代码中的异常是无法使用 try…catch
方法捕获的,那么,如何捕获异步程序中的异常呢?Node.js 中提供了两种方法,用于捕获异步程序中的异常,分别如下。
-
process
方式。process
模块是 Node.js 提供给开发者用来和当前进程进行交互的工具,通过监听它的uncaughtException
事件,可以处理所有未被捕获的异常,包括同步代码块中的异常和异步代码块中的异常。例如,下面代码用来捕获本节开始定义的异步代码中的异常:process.on('uncaughtException', function (e) { console.log(e.message) //处理异常 }); asyncError()
-
domain
方式。通过监听domain
模块的error
事件来处理异步代码块中的异常,domain
模块主要用来简化异步代码的异常处理,它可以处理try…catch
无法捕捉的异常。例如,下面代码使用domain
方式捕获本节前面定义的异步代码中的异常:let domain = require('domain') let d = domain.create() d.on('error', function (e) { console.log(e.message) //处理异常 }) d.run(asyncError)
使用 |