【问题标题】:Koa.js: Centralized error handlingKoa.js:集中式错误处理
【发布时间】:2018-12-27 10:52:08
【问题描述】:

我通过 Mongoose 使用 Koa.js 和 MongoDB。我想知道如何实现一个完美的集中式错误处理机制。

例如,我编写的通过 Mongoose 连接到 MongoDB 的函数存在一些问题。这就是为什么我收到以下错误。但是,我想捕获此错误并以集中方式处理它。意思是,我希望所有错误和警告(无论来自应用程序的哪个部分)都由我的应用程序中的一个函数处理,该函数将记录它。

warning.js:18 (node:11776) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): MongoNetworkError: failed to connect to server [127.0.0.1:27017] on first connect [MongoNetworkError: read ECONNRESET]
    writeOut @ warning.js:18
    output @ warning.js:69
    process.on @ warning.js:100
    emitOne @ events.js:116
    emit @ events.js:211
    (anonymous) @ warning.js:74
    _combinedTickCallback @ next_tick.js:131
    _tickCallback @ next_tick.js:180
    TickObject (async)
    init @ inspector_async_hook.js:22
    emitInitNative @ async_hooks.js:472
    emitInitScript @ async_hooks.js:388
    nextTick @ next_tick.js:270
    process.emitWarning @ warning.js:146
    emitWarning @ promises.js:75
    emitPendingUnhandledRejections @ promises.js:95
    _tickCallback @ next_tick.js:189
    Show 11 more blackboxed frames

warning.js:18 (node:11776) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
    writeOut @ warning.js:18
    output @ warning.js:69
    process.on @ warning.js:100
    emitOne @ events.js:116
    emit @ events.js:211
    (anonymous) @ warning.js:74
    _combinedTickCallback @ next_tick.js:131
    _tickCallback @ next_tick.js:180
    TickObject (async)
    init @ inspector_async_hook.js:22
    emitInitNative @ async_hooks.js:472
    emitInitScript @ async_hooks.js:388
    nextTick @ next_tick.js:270
    process.emitWarning @ warning.js:146
    emitWarning @ promises.js:78
    emitPendingUnhandledRejections @ promises.js:95
    _tickCallback @ next_tick.js:189
    Show 11 more blackboxed frames

warning.js:18 (node:11776) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): MongoNetworkError: failed to connect to server [127.0.0.1:27017] on first connect [MongoNetworkError: read ECONNRESET]
    writeOut @ warning.js:18
    output @ warning.js:69
    process.on @ warning.js:100
    emitOne @ events.js:116
    emit @ events.js:211
    (anonymous) @ warning.js:74
    _combinedTickCallback @ next_tick.js:131
    _tickCallback @ next_tick.js:180
    TickObject (async)
    init @ inspector_async_hook.js:22
    emitInitNative @ async_hooks.js:472
    emitInitScript @ async_hooks.js:388
    nextTick @ next_tick.js:270
    process.emitWarning @ warning.js:146
    emitWarning @ promises.js:75
    emitPendingUnhandledRejections @ promises.js:95
    _tickCallback @ next_tick.js:189
    Show 11 more blackboxed frames

【问题讨论】:

    标签: node.js mongoose error-handling koa koa2


    【解决方案1】:

    以下代码将确保任何未处理的承诺错误或任何未捕获的错误,如果未在本地处理,将得到处理:

    app.use(async (ctx, next) => {
      try {
        await next();
      } catch (err) {
        ctx.status = err.status || 500;
        ctx.body = err.message;
        ctx.app.emit('error', err, ctx);
      }
    });
    
    ...
    
    someUnhandledError();
    
    ...
    
    
    process.on("unhandledRejection", (reason: string) => {
      // I just caught an unhandled promise rejection,
      // let's throw it here so my central error handler can catch it
      throw new AppError(reason, 500);
    });
    
    process.on('uncaughtException', (error: Error) => {
      // I just received an error that was never handled, time to handle it
      // by throwing it so my error handling middleware can catch it
      throw new AppError("Error", 500)
    });
    
    app.on('error', (err, ctx) => {
      // centralized error handling:
      // console.log(error)
      // write error to log file
    });
    
    app.listen(3000);
    

    注意:这里使用的AppError 类是扩展Error 类的自定义类。

    【讨论】:

      【解决方案2】:

      在 Koa wiki 中有一个关于错误处理的部分:https://github.com/koajs/koa/wiki/Error-Handling

      他们建议使用错误处理程序中间件作为应用程序中的第一个中间件,这样下游抛出的任何错误都会冒泡到它上面。

      他们来自 wiki 的示例:

      app.use(async (ctx, next) => {
        try {
          await next();
        } catch (err) {
          ctx.status = err.status || 500;
          ctx.body = err.message;
          ctx.app.emit('error', err, ctx);
        }
      });
      
      app.on('error', (err, ctx) => {
        /* centralized error handling:
         *   console.log error
         *   write error to log file
         *   save error and request information to database if ctx.request match condition
         *   ...
        */
      });
      

      【讨论】:

      • 但这并没有发现任何错误,比如说服务器何时初始化或刚刚启动等,基本上在这个app.use函数之前。
      猜你喜欢
      • 2016-03-05
      • 1970-01-01
      • 2016-05-03
      • 2015-02-05
      • 1970-01-01
      • 2012-08-17
      • 2018-03-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多