在 eggjs 的错误处理中插入 sequelize 事务回滚

厌烦了每个 controller 都必须加入一个 try ... catch ..., 明明有一个最后包住的错误处理,还是每次都写这种垃圾代码。

已经在 config.onerror 的配置里加入了自定义的错误码处理,现在还需要加入事务的自动回滚。问题就在于这个是个异步操作。sequelize 返回的是一个 Promise. 直接加入能够执行。但执行顺序上似乎不太理想。

这是第一次卡住的地方。怎么样在一个请求的末端再加入异步操作?觉得自己是被这个思路限制住了。回顾一下 koa 的调用链,这不就是一个 middleware 的事吗?

  // middleware after error handling
  module.exports = async function (ctx, next) {
    console.log('this is middleware working');
    await next();
    console.log('this is middleware logging after error handling');
  }

还是太年轻了,错误处理之后,请求就结束,返回响应了。

看了一下 koa 的代码,应该是这一行下面的 onFinished 的作用。

  // https://github.com/koajs/koa/blob/master/lib/application.js#L150
  class Application extends Emitter {
    // ...
    handleRequest(ctx, fnMiddleware) {
      const res = ctx.res;
      res.statusCode = 404;
      const onerror = err => ctx.onerror(err);
      const handleResponse = () => respond(ctx);
      onFinished(res, onerror);
      return fnMiddleware(ctx).then(handleResponse).catch(onerror);
    }
    // ...
  }

更多的需要更加深入的学习 koa 代码了。

回到原来的问题。

async 函数的传染性麻烦就麻烦在这里,你是将一个回调注入到第三方仓库的代码中。如果是自己的代码,再不济全链路 async 就是了,但这里是绝对不行的。

这里也不可能用回调的方法,因为回调的调用方不是你,你也没办法再定义一个。再改可能就要对 emitter 相关的东西做 hack 了。

只有退而取其次了。一开始的方案也不是不可以接受的。很多场景下把一些业务放到背景然后先响应甚至都是必要的,比如批量操作。做好日志就行了。

你可能感兴趣的:(在 eggjs 的错误处理中插入 sequelize 事务回滚)