node项目中的错误处理
node中Error对象的使用
使用captureStackTrace方法加入自带的错误信息
// Error对象自带的属性Error.captureStackTrace// 如何使用captureStackTracevar obj = { message: 'something is wrong'}Error.captureStackTrace(obj)throw obj // 此时会抛出obj对象的message内信息
使用try catch捕获错误
直接把代码写在try catch中即可捕获错误信息
try{ throw new Error('oh no')}catch(e){ console.log(e)}
在异步代码中,直接try catch是无法捕获错误信息的,可以使用如下方法
function foo(params, cb){ const error = new Error('something is wrong') if(error) cb(error)}
以上使用callback方式来做错误处理比较容易麻烦,容易出错,现在node已经支持async await所以尽量使用它们准没错
async function foo(){ try{ await bar() }catch(e){ console.log(e) }}async function bar(){ throw new Error('async function got wrong)}foo()
基本错误类型
在项目会有多个地方对错误信息进行处理,所以先写一个基本错误类型,方便使用
// 基本错误类型class HttpBaseError extends Error { constructor(httpStatusCode, httpMsg, errCode, msg) { super(`HTTP ERROR: ${msg}`); this.httpStatusCode = httpStatusCode; this.httpMsg = httpMsg; this.errCode = errCode; }}try {// 直接抛出定义好的错误即可 throw new HttpBaseError(404, '资源不存在', 10000, 'resouse is not found');} catch (e) { console.log(e.message); console.log(e.httpStatusCode); console.log(e.httpMsg); console.log(e.errCode);}
特定错误类型
除了基本类型,不同情况下会有不同错误信息,需要用一个特定的错误类型来处理特定的错误信息
// 一个参数错误类型const ERROR_CODE = 40000 // 错误码class HttpRequestParamError extends HttpBaseError { constructor(paramName, desc, msg) { super(200, desc, ERROR_CODE, `${paramName} wrong: ${msg}`) }}
这样,在参数错误的地方就能非常方便的调用这个错误类型来返回错误
抛错的逻辑
错误处理中,model,controller中的错误,有些是不能直接返回给用户的,应该只返回给model或controller的调用者。
使用错误处理
正常接口,controller,model的错误,使用设定好的错误类型进行处理,例如前面写的HttpRequestParamError,在所有所有路由的最后,需要使用一个error handler来对所有的错误进行集中处理
// error handlerfunction handler(options) { return function (err, req, res, next) { if (err instanceof HttpRequestParamError) { // 这里对不同的错误做不同的处理 console.log('http request error') res.statusCode = err.httpStatusCode res.json({ code: err.errCode, msg: err.httpMsg }) } else { // 设定之外的错误,把管理权向外移交 next(err) } }}
新闻热点
疑难解答
图片精选