even

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、nest.js的异常处理

Nest 框架内部实现了一个异常处理层,专门用来负责应用程序中未处理的异常。

nest.js内置的异常类有:

  • BadRequestException
  • UnauthorizedException
  • NotFoundException
  • ForbiddenException
  • NotAcceptableException
  • RequestTimeoutException
  • ConflictException
  • GoneException
  • HttpVersionNotSupportedException
  • PayloadTooLargeException
  • UnsupportedMediaTypeException
  • UnprocessableEntityException
  • InternalServerErrorException
  • NotImplementedException
  • ImATeapotException
  • MethodNotAllowedException
  • BadGatewayException
  • ServiceUnavailableException
  • GatewayTimeoutException
  • PreconditionFailedException

但是这些类全部继承于  HttpException, 所以通常我们抛出异常的写法有如下方法

@Get('test')
public getTest() {
  throw new HttpException(
    {
      status: HttpStatus.FORBIDDEN,    //这里面的字段都是定制字段
      error: 'This is a custom message',
      data: []
    },
    HttpStatus.NOT_FOUND  //http码
  );
  // throw new HttpException('error', HttpStatus.PARTIAL_CONTENT);
  // throw new ForbiddenException(); //禁止访问错误, 参数1表示message, 参数2是一个error, 直接使用内置的异常类
}

注意: 可以使用HttpException进行异常的抛出,也可以使用内置的方法进行异常的抛出

 

自定义异常类

export class ForbiddenException extends HttpException {
  constructor() {
    super('Forbidden', HttpStatus.FORBIDDEN);
  }
}

使用自定义异常类

@Get()
async findAll() {
  throw new ForbiddenException();
}

如果需要在异常中添加指定的数据,比如需要在异常类中添加请求地址,或者参数, 又或者添加日志的写入等,那么可以定义个异常过滤器

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

@Catch()
export class AllExceptionsFilter implements ExceptionFilter {
  catch(exception: unknown, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const status =
      exception instanceof HttpException
        ? exception.getStatus()
        : HttpStatus.INTERNAL_SERVER_ERROR;

//这里可以添加些日志操作 response.status(status).json({ statusCode: status, timestamp:
new
Date().toISOString(), path: request.url, }); } }

注意: 这里exception中有两个方法,exception.getStatus()  exception.getResonse() 一个是获取异常的错误码,一个是获取异常的信息:里面包含错误码以及原本的message

使用异常过滤器的两种方式

@Post()
@UseFilters(new HttpExceptionFilter())
// @UseFilters(HttpExceptionFilter)
async create(@Body() createCatDto: CreateCatDto) {
  throw new ForbiddenException();
}

可以定义全局异常过滤器

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);

  ...

  app.useGlobalFilters(new HttpExceptionFilter());  // 注意这里只能使用new这个关键字来实现实例化

  await app.listen(3000);
}
bootstrap();

 通常来讲还有一种方式实现全局异常过滤器

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: HttpExceptionFilter,
    },
  ],
})
export class AppModule {}

注意:不管在哪个模块进行声明定义,那么作用范围将是全局的

 

2、nest.js日志

Nest附带一个默认的内部日志记录器实现,它在实例化过程中以及在一些不同的情况下使用,比如发生异常等等。但是,有时您可能希望完全禁用日志记录,或者提供自定义实现并自己处理消息。为了关闭记录器,我们使用Nest应用程序选项对象。

const app = await NestFactory.create(ApplicationModule, {
  //关闭log
  logger: false, 
  //只启用指定的log级别
  logger: ['warn', 'error'] 
});
await app.listen(3000);

注意:log的等级有'log''error''warn''debug', 和 'verbose'.

在某些场景中,我们可能希望在底层使用不同的日志记录器。为此,我们必须传递一个实现LoggerService接口的对象。例如,一个内置的控制台。

const app = await NestFactory.create(ApplicationModule, {
  logger: console,
});
await app.listen(3000);

但这不是一个最好的办法,我们也可以选择创建自定义的记录器:

import { LoggerService } from '@nestjs/common';

export class MyLogger implements LoggerService {
  log(message: string) {}
  error(message: string, trace: string) {}
  warn(message: string) {}
  debug(message: string) {}
  verbose(message: string) {}
}

然后,我们可以MyLogger直接应用实例:

const app = await NestFactory.create(ApplicationModule, {
  logger: new MyLogger(),
});
await app.listen(3000);

扩展内置的日志类

很多实例操作需要创建自己的日志。你不必完全重新发明轮子。只需扩展内置Logger类以部分覆盖默认实现,并使用super将调用委托给父类。

import { Logger } from '@nestjs/common';

export class MyLogger extends Logger {
  warn(message: string, trace: string) {
    // 写入自己的逻辑
    super.warn(message, trace);
  }
  error(message: string, trace: string) {
    // 写入自己的逻辑
    super.error(message, trace);
  }
}

依赖注入

如果要在Logger类中启用依赖项注入,则必须使MyLogger该类成为实际应用程序的一部分。例如,您可以创建一个LoggerModule:

import { Module } from '@nestjs/common';
import { MyLogger } from './my-logger.service.ts';

@Module({
  providers: [MyLogger],
  exports: [MyLogger],
})
export class LoggerModule {}

一旦LoggerModule在其他地方导入,框架将负责创建Logger类的实例。现在,要在整个应用程序中使用相同的Logger实例,包括引导和错误处理的东西,请使用以下方式:

const app = await NestFactory.create(ApplicationModule, {
  logger: false,
});
app.useLogger(app.get(MyLogger));
await app.listen(3000);

 

posted on 2021-07-24 07:02  even_blogs  阅读(239)  评论(0编辑  收藏  举报