nest为响应码设定message文本,基于异常过滤器

需求

需要对接口的异常响应码,手动设置message文本!!!

例如:项目中使用multer中间件实现文件上传,multer设置了文件大小限制,该中间件校验文件时错误(文件超出)会自动响应为:

status: 413
statusMessage: 'Playload Too Large' 

// 响应数据
{
    "message": "File too large",
    "error": "Payload Too Large",
    "statusCode": 413
}

但是我想自定义设置该message的文本,甚至是设置statusMessage文本

实现

通过局部异常过滤器实现

custom-exception.filter.ts

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
  Logger,
} from '@nestjs/common';

/**
 * 自定义异常过滤器
 * 为指定响应码设置message文本
 *
 * 例子: 文件上传中间件校验文件大小, 失败会自动响应为413, message为File too large
 *    我想将message设置为 '文件过大',  就可以使用该过滤器
 *
 * 使用方式:  在controller层接口函数上添加:
 *    @UseFilters(new CustomExceptionFilter(new CodeMessage(413, '文件过大')))
 *    @UseFilters(
 *      new CustomExceptionFilter([
 *        new CodeMessage(413, '文件过大'),
 *        new CodeMessage(415, '文件格式错误'),
 *      ]),
 *    )
 *    @UseFilters(new CustomExceptionFilter({ code: 413, message: '文件大小错误' }))
 *
 * (CodeMessage对象中: code用于匹配响应码, message为要设置的文本)
 */

@Catch()
export class CustomExceptionFilter implements ExceptionFilter {
  // 允许传入对象或者对象数组
  constructor(private readonly referenceData: CodeMessage | CodeMessage[]) {}

  catch(exception: Error, host: ArgumentsHost) {
    const ctx = host.switchToHttp(); // 获取请求上下文
    const request = ctx.getRequest(); // 获取请求上下文中的request对象
    const response = ctx.getResponse(); // 获取请求上下文中的response对象

    // 获取异常状态码
    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

    // 响应数据的错误码和错误信息
    let code = 500;
    let message = '服务器错误(Service Error)';

    // 取传入数据中对应的code与message,  可能是数组或对象
    if (Array.isArray(this.referenceData)) {
      for (let i = 0; i < this.referenceData.length; i++) {
        const item = this.referenceData[i];

        if (item.code === status) {
          code = item.code;
          message = item.message;

          break;
        }
      }
    } else if (
      Object.prototype.toString.call(this.referenceData) ===
        '[object Object]' &&
      this.referenceData.code === status
    ) {
      code = this.referenceData.code;
      message = this.referenceData.message;
    }

    // 响应数据
    const errorResponse = {
      code,
      message,
      errorMessage: exception.message,
    };

    // 将异常记录到logger中
    Logger.error(`异常 >>>> 【${new Date()}${request.method} ${request.url}`);
    Logger.error(`query: ${JSON.stringify(request.query)}`);
    Logger.error(`params: ${JSON.stringify(request.params)}`);
    Logger.error(`body: ${JSON.stringify(request.body)}`);
    Logger.error(`error: ${exception}`);
    Logger.error(`errorResponse: ${JSON.stringify(errorResponse)}`);

    // 设置返回的状态码, 请求头,发送错误信息
    response.setHeader('Content-Type', 'application/json; charset=gb2312');
    response.status(status);
    // response.statusMessage = message;
    response.send(errorResponse);
  }
}

// 码对应消息
export class CodeMessage {
  code: number;
  message: string;

  constructor(code: number, message: string) {
    this.code = code;
    this.message = message;
  }
}

使用

  /**
   * 中间件实现上传
   * @param file
   */
  @Post('test')
  @UseFilters(new CustomExceptionFilter(new CodeMessage(413, '文件过大')))
  // @UseFilters(
  //   new CustomExceptionFilter([
  //     new CodeMessage(413, '文件过大'),
  //     new CodeMessage(415, '文件格式错误'),
  //   ]),
  // )
  // @UseFilters(new CustomExceptionFilter({ code: 413, message: '文件过大' }))
  test() {
    throw new HttpException('模拟异常', 413);
    return 'OK';
  }
  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值