【问题标题】:How to make koa ctx.throw() use application/json rather than text/plain如何让 koa ctx.throw() 使用 application/json 而不是 text/plain
【发布时间】:2019-03-08 11:36:32
【问题描述】:

我为我的 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;

error-handler.js:

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

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

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

【问题讨论】:

    标签: javascript koa


    【解决方案1】:

    设法修改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);
      });
    };
    

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

    值得一提的是,这个自定义错误 - ServerError.js - 在应用程序中使用;这就是为什么 ctx.status = statusCode || 500 - statusCode 在使用时由 ServerError 提供,但对于抛出的非自定义错误,statusCode 会传递给 error-handler.js 作为 undefined 所以需要 || 500

    ServerError.js:

    export class ServerError extends Error {
      constructor(statusCode, message) {
        super(message);
        this.statusCode = statusCode;
      }
    }
    

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

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

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

    【讨论】:

    • 试过这种方法,使用节点请求只从 res.body 得到一个“Internal Server Error”,使用Superkoa运行测试,res.body 仍然是整个字符串输出,而不是一个 JSON 对象。有什么方法可以捕获对象中的有效负载,以便客户端了解出了什么问题?
    猜你喜欢
    • 1970-01-01
    • 2021-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-30
    • 2020-02-26
    • 2011-05-20
    • 2018-05-12
    相关资源
    最近更新 更多