美文网首页
Nodejs异常处理

Nodejs异常处理

作者: 黑曼巴yk | 来源:发表于2019-11-21 23:46 被阅读0次

使用场景

异常分类
  • 非期望的入参,如函数要求传递的是数值,却传递了字符串
  • 意料之外的错误,如:HTTP网络端开,文件不存在等
  • 完全意料之外的异常,如业务进程被外部杀死
通用实践
  • 需要记录错误的信息,位置,堆栈和上下文
  • 根据内容协商来返回不同的响应格式
  • 正式环境中,不能将详细的错误信息和堆栈抛到用户侧

Nodejs异常处理

Nodejs里,对异常的处理非常重要,如果有未捕获异常会直接导致进程退出。
Async Function异步编程模型出来后,通过try...catch来捕获错误,就直观的很多。

框架内置支持

egg.js内置了onerror插件,提供了统一的错误处理机制
对一个请求处理过程中的Middleware,Controller,Service等抛出的任何异常都会被它捕获。

业务错误处理

可以使用middleware进行统一处理

// app/middleware/error_handler.js
module.exports = () => {
  return async function errorHandler(ctx, next) {
    try {
      await next();
    } catch (err) {
      const { app } = ctx;
      // 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志
      app.emit('error', err, ctx);

      const status = err.status || 500;

      // 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息
      const error = status === 500 && app.config.env === 'prod' ? 'Internal Server Error' : err.message;

      // 仅供参考,需按自己的业务逻辑处理。
      ctx.body = { error };
      ctx.status = status;
    }
};

挂载中间件:

module.exports = {
  middleware: [ 'errorHandler' ],
  errorHandler: {
    // 仅对该路径下的接口处理
    match: '/api',
  },
};

框架兜底处理

框架通过onerror插件提供了统一错误处理机制
对一个请求所有的处理方法(Middleware、Controller、Service)中抛出的任何异常都会被它捕获。


image.png
自定义统一异常处理

尽管框架提供了默认统一异常处理机制,但是应用开发经常需要对异常的响应做自定义,特别是在做一些接口开发的时候。框架自带的 onerror 插件支持自定义配置错误处理方法,可以覆盖默认的错误处理方法。

// config/config.default.js
module.exports = {
  onerror: {
    all(err, ctx) {
      // 在此处定义针对所有响应类型的错误处理方法
      // 注意,定义了 config.all 之后,其他错误处理方法不会再生效
      ctx.body = 'error';
      ctx.status = 500;
    },
    html(err, ctx) {
      // html hander
      ctx.body = '<h3>error</h3>';
      ctx.status = 500;
    },
    json(err, ctx) {
      // json hander
      ctx.body = { message: 'error' };
      ctx.status = 500;
    },
    jsonp(err, ctx) {
      // 一般来说,不需要特殊针对 jsonp 进行错误定义,jsonp 的错误处理会自动调用 json 错误处理,并包装成 jsonp 的响应格式
    },
  },
};
自定义404响应

在一些场景下,我们需要自定义服务器 404 时的响应,只需要加入一个中间件即可统一处理:

// app/middleware/notfound_handler.js
module.exports = () => {
  return async function notFoundHandler(ctx, next) {
    await next();
    if (ctx.status === 404 && !ctx.body) {
      if (ctx.acceptJSON) {
        ctx.body = { error: 'Not Found' };
      } else {
        ctx.body = '<h1>Page Not Found</h1>';
      }
    }
  };
};

常见问题

该不该 Catch

如果错误是非主流程的,是可选的,可以使用try...catch自行兜底处理。

回调错误无法捕获

正常的写法,所有的异常都可以捕获并处理,但是有些特殊的写法可能带来问题。
所有的异步操作都通过await串联起来,但是只要有一个地方跳出来异步调用链,异常就捕获不到了。

// app/controller/home.js
class HomeController extends Controller {
  async buy () {
    const { ctx } = this;

    const config = await ctx.service.trade.buy({ id: '12345' });
    // 下单后需要进行一次核对,且不阻塞当前请求
    setImmediate(() => {
      ctx.service.trade.check(request).catch(err => ctx.logger.error(err));
    });
  }
}

但是由于 setImmediate 中的代码『跳出』了异步链,它里面的错误就无法被捕捉到了。
框架提供了ctx. runInBackground (scope)辅助方法,通过它包装了一个异步链,所有在这个scope里面的错误都会统一进行捕获。

class HomeController extends Controller {
  async buy () {
    const request = {};
    const config = await ctx.service.trade.buy(request);
    // 下单后需要进行一次核对,且不阻塞当前请求
    ctx.runInBackground(async () => {
      // 这里面的异常都会统统被 Backgroud 捕获掉,并打印错误日志
      await ctx.service.trade.check(request);
    });
  }
}

相关文章

  • Nodejs异常处理

    使用场景 异常分类 非期望的入参,如函数要求传递的是数值,却传递了字符串 意料之外的错误,如:HTTP网络端开,文...

  • Nodejs学习笔记-异常处理

    同步捕获异步捕获异常抛出 代码:https://github.com/fengchunjian/nodejs_ex...

  • nodejs异常事件处理

    node运行过程中,如遇到没有捕获异常,则自行中断退出。 像缺少依赖等常见问题,还好办;但像AEDDRINUSE这...

  • nodejs捕获未处理异常-uncaughtException

    我们可以uncaughtException或者unhandledRejection来全局捕获未捕获的Error,同...

  • Nodejs异步回调之异常处理实例

    目前我们项目的Nodejs异常是通过express next 到 errorhandler 中间件去处理的,原本以...

  • Nodejs异步回调之异常处理

    目前我们项目的Nodejs异常是通过express next 到 errorhandler 中间件去处理的,原本以...

  • 异步I/O的难点

    其实异步的I/O的难点与不适,在NodeJs,甚至JavaScript中有这很具体的体现。 难点1:异常处理难。 ...

  • NodeJs+Koa学习4、异步异常和全局异常处理

    1.参数传递 参数传递有几种方式: 1.路径中传参 使用:id 这种方式 2.路径后面跟 使用get请求 3.he...

  • 同步或异步异常处理

    同步或异步异常处理 同步读取异常处理 异步读取文件异常处理

  • Java 异常

    异常处理机制 异常处理模型:终止模型:当异常发生时,就进入异常处理程序,处理结束并不返回异常发生位置继续执行;恢复...

网友评论

      本文标题:Nodejs异常处理

      本文链接:https://www.haomeiwen.com/subject/byvxwctx.html