NestJS 7.x 折腾记: (6) 异常过滤器,取其精华去其糟粕!比如响应异常数据的包装~

简介: 正如官方所说:内置的异常层负责处理整个应用程序中的所有抛出的异常。当捕获到未处理的异常时,最终用户将收到友好的响应。

网络异常,图片无法展示
|


前言


正如官方所说:


内置的异常层负责处理整个应用程序中的所有抛出的异常。


当捕获到未处理的异常时,最终用户将收到友好的响应。


网络异常,图片无法展示
|


NestJS提供了一波拿来即用的内置异常过滤器;


@nestjs/common里面,搜索下Exception就有~


我们来一个具体的例子(全局异常过滤),


基于内置的异常过滤器实现,采用第三方日志(pino)记录异常日志,


做一些处理并包裹返回信息;


效果图


网络异常,图片无法展示
|


实战


# 基于cli生成filter模板
nest g f common/filters/http-exception


http-exception.filter.ts


// 日期格式化库,很小巧,类moment 风格api
import * as dayjs from 'dayjs';
import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
  HttpStatus,
} from '@nestjs/common';
// nest默认底层是基于express封装,所以可以直接引入
import { Request, Response } from 'express';
// 第三方logger
import { Logger } from 'nestjs-pino';
// 捕获请求异常类型
// 可以传递多个参数,所以你可以通过逗号分隔来为多个类型的异常设置过滤器。
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  // 我们要把异常塞到自定义logger,必须引入对应的实例
  // 在构建函数声明定义下,从外部传入
  constructor(private readonly logger: Logger) {}
  catch(exception: HttpException, host: ArgumentsHost) {
    // 把请求相关的参数转成标准http的上下文
    // 有兴趣可以点进去,GPRC,WEBSOCKET都能直接转换
    // 也能直接拿到一些参数的及返回上下文类型
    const ctx = host.switchToHttp();
    // 响应体
    const response = ctx.getResponse<Response>();
    // 请求体
    const request = ctx.getRequest<Request>();
    // 判断状态是否为请求异常,否则直接抛回来服务内部错误
    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;
    // 此刻的时间
    const nowDate = dayjs(Date.now()).format('YYYY-MM-DDTHH:mm:ss');
    // 包装异常信息
    const errorResponse = {
      statusCode: status,
      message: exception.message,
      error: exception.name,
      date: nowDate,
      path: request.url,
    };
    // 记录异常信息到第三方logger
    this.logger.error(
      `【${nowDate}】${request.method} ${request.url} query:${JSON.stringify(
        request.query,
      )} params:${JSON.stringify(request.params)} body:${JSON.stringify(
        request.body,
      )}`,
      JSON.stringify(errorResponse),
      'HttpExceptionFilter',
    );
    // 塞回去响应体,也就是客户端请求可以感知到的
    response.status(status).json(errorResponse);
  }
}


主入口(main.ts)


import { AppModule } from './app.module';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
import { Logger } from 'nestjs-pino';
import { NestFactory } from '@nestjs/core';
async function bootstrap() {
  const app = await NestFactory.create(AppModule, {
    cors: false,
    logger: false,
  });
  // 获取pino logger实例 
  const logger = app.get(Logger);
  // nestjs-pino 取代nest logger
  app.useLogger(logger);
  // 设置全局异常过滤器
  app.useGlobalFilters(new HttpExceptionFilter(logger));
  await app.listen(configService.get('SERVE_LISTENER_PORT'));
}
bootstrap()


app.module.ts


若是只要特定模块生效可以使用Providers去实现,从核心模块导出;


import { Module } from '@nestjs/common';
// 包括网关,拦截器都可以走这种模式!
import { APP_FILTER } from '@nestjs/core';
import { HttpExceptionFilter } from './common/filters/http-exception.filter';
@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}


若是加上@Global装饰器也能达到全局模块的效果!


这个东东一般不推荐用在app.module,而是你需要导出的复用模块!


这里只是演示写法


import { Module,Global } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
@Global()
@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}


@Global() 推荐用于给外部复用,又需要变成全局模块的,比如


import { Module, Global } from '@nestjs/common';
import { CatsController } from './cats.controller';
import { CatsService } from './cats.service';
@Global()
@Module({
  controllers: [CatsController],
  providers: [CatsService],
  exports: [CatsService],
})
export class CatsModule {}
目录
相关文章
|
24天前
|
前端开发 JavaScript API
异步请求中的错误处理可以放在哪个阶段?
【10月更文挑战第29天】异步请求中的错误处理可以根据不同的错误类型和需求,放在请求发起、请求过程、请求响应以及数据处理等多个阶段进行,通过全面而细致的错误处理,可以提高应用程序的稳定性和可靠性,为用户提供更好的体验。
|
24天前
|
监控 前端开发 JavaScript
如何处理异步请求中的错误?
【10月更文挑战第29天】通过以上多种方法的综合运用,可以全面地处理异步请求中的各种错误,提高应用程序的稳定性和可靠性,同时为用户提供更好的错误反馈和体验。在实际开发中,应根据具体的项目需求和应用场景,选择合适的错误处理策略和方法,并进行充分的测试和优化。
|
5月前
|
文字识别 Java
文本,文字识别12,接口返回值和异常封装,一个好的接口,应该包括,错误码,提示信息,返回的数据,应该知道出错,错在哪里,抛出业务异常应该怎样解决?出现业务异常的时候,抛出业务异常,全局异常处理
文本,文字识别12,接口返回值和异常封装,一个好的接口,应该包括,错误码,提示信息,返回的数据,应该知道出错,错在哪里,抛出业务异常应该怎样解决?出现业务异常的时候,抛出业务异常,全局异常处理
|
7月前
|
前端开发 程序员
项目中异常是如何处理的
项目中设定了全局异常处理器,统一处理预期和运行时异常。预期异常由程序员手动抛出,用于异常情况的接口返回;运行时异常为不可控错误,提供统一返回格式便于前端提示和后端排查。全局异常处理器借助@RestControllerAdvice和@ExceptionHandler注解,前者标识处理器,后者按异常类型定制前端响应,如预期异常直接返回,运行时异常则调整响应内容。
98 0
|
7月前
|
前端开发 数据可视化 Dubbo
深入解析 Axios 取消请求:2 种方法助你掌握控制权
在前端开发中,网络请求是非常常见的操作。而有时候,我们可能需要在发送请求后取消它,比如用户在请求还未完成时离开了当前页面或者执行了其他操作,本文将介绍如何在使用 Axios 发送请求时取消这些请求。
深入解析 Axios 取消请求:2 种方法助你掌握控制权
|
7月前
|
前端开发
Nestjs(五)异常处理方式(异常过滤器)
Nestjs(五)异常处理方式(异常过滤器)
134 0
|
数据采集 数据安全/隐私保护
如何使用异常处理机制捕获和处理请求失败的情况
在爬虫开发中,我们经常会遇到请求失败的情况,比如网络超时、连接错误、服务器拒绝等。这些情况会导致我们无法获取目标网页的内容,从而影响爬虫的效果和效率。为了解决这个问题,我们需要使用异常处理机制来捕获和处理请求失败的情况,从而提高爬虫的稳定性和稳定性。
124 0
如何使用异常处理机制捕获和处理请求失败的情况
|
JSON 前端开发 数据格式
前端对接口参数错误如何解决
前端对接口参数错误如何解决
93 0
|
JSON 前端开发 数据格式
前端对接口参数错误如何解决
前端对接口参数错误如何解决
128 0
|
测试技术 数据处理 数据安全/隐私保护
接口自动化测试中一些复杂请求的处理方式
接口自动化用例编写中,遇到复杂的请求数据,该如何处理?