Nodejs常用异常处理方式

Nodejs异常处理方法

在 Node.js 中,在不开启多进程的默认情况下,所有请求都会走进同一份JS代码,并且只有一个线程在执行这份JS代码。如果某个用户的请求,导致发生错误,Node.js进程挂掉,server端直接就挂了。尽管可能有进程守护,挂掉的进程会被重启,但是在用户请求量大的情况下,错误会被频繁触发,可能就会出现 server 端不停挂掉,不停重启的情况,对用户体验造成影响。

由于Node.js语言的特性,Node服务是比较容易出错的。而一旦出错,造成的影响就是服务不可用。因此对于错误的处理十分的重要。

try catch

处理异常最常用的就是 try catch 语句了。但是 try catch 无法捕获异步错误。Node.js 中,异步操作是十分常见的,异步操作主要是在回调函数中暴露错误。例如:

const readFile = function(path) {  
    return new Promise((resolve,reject) => {  
        fs.readFile(path, (err, data) => {  
            if(err) {   
                throw err // catch无法捕获错误,这和Node的eventloop有关。  
        // reject(err) // catch可以捕获  
      }  
      resolve(data)
        })
    })
} 
router.get('/xxx', async function(req, res) {  
  try {  
    const res = await readFile('xxx')
    // do sth
  } catch (e){  
    // 捕获错误处理  
    // do sth
    res.send(500)
  }  
})

上面的代码中,readFile 中 throw 出来的错误,是无法被 catch 捕获的。如果我们把 throw err 换成 Promise.reject (err),catch 中是可以捕获到错误的。

我们可以把异步操作都 Promise 化,然后统一使用 async 、try、catch 来处理错误。

process

但是,如果有地方被遗漏。这个时候,可以使用 process 来捕获全局错误,防止进程直接退出,导致后面的请求挂掉。示例代码:

process.on('uncaughtException', (err) => {  
  console.error(`${err.message}\n${err.stack}`) 
})
process.on('unhandledRejection', (reason, p) => {  
  console.error(`Unhandled Rejection at: Promise ${p} reason: `, reason)
})

Node.js的异常捕获,还可以使用 domain 模块。目前这个模块已经不推荐使用了了。Node.js 新推出的 async_hooks 模块,目前不太建议线上环境直接使用。最简单直接的办法是开启进程守护,开启多进程,及时查看错误告警log及时修复,使用合适的框架,提高服务的效率和稳定性。

对你有帮助?请作者喝杯咖啡~
Lau 支付宝 支付宝
Lau 微信 微信
0%