如何让 koa ctx.throw() 使用 application/json 而不是 text/plain

And*_*ndy 6 javascript koa

我为我的 koa 应用程序制作了一个自定义错误处理程序,它运行良好(除了一个症结点) - 使用 ctx.throw()意味着任何堆栈跟踪都被发送到服务器日志,并且任何自定义错误消息都会在响应中发送。

一个问题是,Content-Type标题是text/plain,但我真的需要它application/json

app.js

import Koa from 'koa';
import bodyParser from 'koa-bodyparser';
import logger from 'koa-morgan';

import authentication from './middleware/authentication';
import config from './config';
import errorHandler from './middleware/error-handler';
import notificationsRoutes from './routes/notifications';

const app = new Koa();

app.use(errorHandler);
app.use(bodyParser());
app.use(logger(config.logLevel));
app.use(authentication);
app.use(notificationsRoutes.routes());

export default app;
Run Code Online (Sandbox Code Playgroud)

error-handler.js

export default async (ctx, next) => {
  return next().catch(({ statusCode, message }) => {
    ctx.throw(statusCode, JSON.stringify({ message }));
  });
};
Run Code Online (Sandbox Code Playgroud)

(我想 (statusCode, JSON.stringify({ message }));可能会强制响应,application/json但事实并非如此。

我用谷歌搜索无济于事。请帮忙!

And*_*ndy 8

设法修改error-handler以产生所需的结果。工作得非常好 - 堆栈跟踪被发送到服务器日志,并且该消息的第一行成为message响应正文中的。后者可能被某些人认为是一个缺点,但这取决于您的追求。

error-handler.js:

export default async (ctx, next) => {
  return next().catch(err => {
    const { statusCode, message } = err;

    ctx.type = 'json';
    ctx.status = statusCode || 500;
    ctx.body = {
      status: 'error',
      message
    };

    ctx.app.emit('error', err, ctx);
  });
};
Run Code Online (Sandbox Code Playgroud)

找到这个并用作参考:https://github.com/koajs/examples/blob/master/errors/app.js

值得一提的是,这个自定义错误- ServerError.js-是在app中使用的;这就是为什么ctx.status = statusCode || 500-在使用时statusCode提供ServerError,但对于抛出的非自定义错误,会根据需要statusCode进行处理。error-handler.jsundefined|| 500

ServerError.js:

export class ServerError extends Error {
  constructor(statusCode, message) {
    super(message);
    this.statusCode = statusCode;
  }
}
Run Code Online (Sandbox Code Playgroud)

(用法:throw new ServerError(400, 'my informative error message');

您的任何中间件中都没有任何catch块,并且错误将一直传播到您的顶级errorHandler中间件app.js(这就是您想要发生的情况)。

koa 中的自定义错误处理似乎产生了许多不同的意见,但这似乎目前对我们来说效果很好。