欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

nestjs中異常過(guò)濾器Exceptionfilter的具體使用

 更新時(shí)間:2021年02月07日 08:47:02   作者:baidixing  
這篇文章主要介紹了nestjs中異常過(guò)濾器Exceptionfilter的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

說(shuō)起Nestjs的異常過(guò)濾器,不能不提.Net的全局過(guò)濾器Filter,功能那是相當(dāng)?shù)膹?qiáng)悍,用理論話(huà)說(shuō)叫AOP 面向切面編程,可謂方便了太多需要異常處理的場(chǎng)景。說(shuō)回Nestjs的異常過(guò)濾器,實(shí)現(xiàn)類(lèi)似的功能,采用相似的處理方式,只不過(guò)一個(gè)面向C#,一個(gè)面向Nodejs,很榮幸的我,在兩個(gè)框架都找到了類(lèi)似的東西。

面向切面編程AOP,是一種類(lèi)似于編程規(guī)范的東東,同門(mén)師兄弟有叫面向接口編程、SOLID原則等等。

Nestjs的異常處理

默認(rèn)異常處理

Nestjs內(nèi)置了默認(rèn)的全局異常過(guò)濾器,處理能夠轉(zhuǎn)換成Httpexception的異常。

如果是Httpexception或其子類(lèi)異常,那么會(huì)返回該異常的JSON格式:

{"exceptionCode":40005,"message":"自定義異常","path":"/"}

如果不是Httpexception或其子類(lèi)異常,那么會(huì)返回:

{"statusCode":500,"message":"Internal server error"}

由于Nestjs采用了內(nèi)置的默認(rèn)異常處理,因此不會(huì)出現(xiàn)由于出現(xiàn)未捕獲的異常導(dǎo)致程序崩潰。

自定義異常過(guò)濾器處理

由于內(nèi)置異常處理返回值格式無(wú)法調(diào)整,因此自定義異常就顯得又為正常。自定義異??梢允狗祷禺惓P畔⒆远x,且可以增加自定義異常編碼,方便客戶(hù)端人員根據(jù)異常編碼進(jìn)行不同的展示。

如何自定義異常?

不重復(fù)造輪子是程序員的自我約束,首先我們新建我們自己的異常基類(lèi):

import { HttpException } from "@nestjs/common";

/**
 * 定義基礎(chǔ)異常類(lèi)
 *
 * @export
 * @class BaseException
 * @extends {HttpException}
 */
export class BaseException extends HttpException {

  /**
   * Creates an instance of BaseException.
   * @param {number} exceptionCode 自定義異常編號(hào)
   * @param {string} errorMessage 提示信息
   * @param {number} statusCode 狀態(tài)碼
   * @memberof BaseException
   */
  constructor(public exceptionCode: number, public errorMessage: string, public statusCode: number) {
    super({ exceptionCode: exceptionCode, errorMessage: errorMessage }, statusCode);
  }

  /**
   * 獲取自定義異常代碼
   *
   * @return {*}
   * @memberof BaseException
   */
  getExceptionCode(): number {
    return this.exceptionCode;
  }

  getErrorMessage(): string {
    return this.errorMessage;
  }

  getStatusCode(): number {
    return this.statusCode;
  }
}

然后我們新建一個(gè)未授權(quán)異常類(lèi)型,其中增加了自定義異常代碼:

import { HttpStatus } from "@nestjs/common";
import { BaseException } from "./base.exception";

export class UnCauhtException extends BaseException {
  constructor() {
    super(40000, "系統(tǒng)運(yùn)行異常,請(qǐng)聯(lián)系管理員!", HttpStatus.FORBIDDEN);
  }
}

建立好了自定義異常,那么我們就需要處理未授權(quán)異常,首先新建自定義異常處理基類(lèi),請(qǐng)注意 此處我們使用的事Express:

import { ArgumentsHost, ExceptionFilter, HttpException } from "@nestjs/common";
import { HttpArgumentsHost } from "@nestjs/common/interfaces";
import { BaseException } from "src/exceptions/base.exception";
import { Response, Request } from "express";

/**
 * 異?;A(chǔ)類(lèi)過(guò)濾器
 *
 * @export
 * @class BaseExceptionFilter
 * @implements {ExceptionFilter<BaseException>}
 */
export abstract class BaseExceptionFilter implements ExceptionFilter<BaseException>
{
  /**
   * 異常類(lèi)捕獲
   *
   * @abstract
   * @param {BaseException} exception
   * @param {ArgumentsHost} host
   * @memberof BaseExceptionFilter
   */
  abstract catch(exception: BaseException, host: ArgumentsHost);

  /**
   * 獲取http請(qǐng)求上下文參數(shù)
   *
   * @protected
   * @param {ArgumentsHost} host
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getHttpContext(host: ArgumentsHost) {
    return host.switchToHttp();
  }

  /**
   * 獲取http 響應(yīng)參數(shù)
   *
   * @protected
   * @param {HttpArgumentsHost} httpContext
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getResponse(httpContext: HttpArgumentsHost): Response {
    return httpContext.getResponse<Response>();
  }

  /**
   * 獲取http請(qǐng)求參數(shù)
   *
   * @protected
   * @param {HttpArgumentsHost} httpContext
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getRequest(httpContext: HttpArgumentsHost): Request {
    return httpContext.getRequest<Request>();
  }

  /**
   * 寫(xiě)入異常信息到客戶(hù)端
   *
   * @param {ArgumentsHost} host
   * @param {BaseException} exception
   * @memberof BaseExceptionFilter
   */
  protected writeToClient(host: ArgumentsHost, exception: BaseException) {
    const ctx = this.getHttpContext(host);
    if(exception instanceof BaseException){
      this.getResponse(ctx).status(exception.statusCode).json({
        exceptionCode: exception.getExceptionCode(),
        message: exception.getErrorMessage(),
        path: this.getRequest(ctx).url
      });
    }else {
      const httpException=exception ;
      this.getResponse(ctx).status(500).json({
        message: "未處理的異常",
        path: this.getRequest(ctx).url
      });
    }

  }
}

新建未授權(quán)異常處理:

import { ArgumentsHost, Catch } from "@nestjs/common";
import { AuthException } from "src/exceptions/auth.exception";
import { BaseException } from "src/exceptions/base.exception";
import { BaseExceptionFilter } from "./base.exception.filter";

@Catch(AuthException)
export class AuthExceptionFilter extends BaseExceptionFilter
{
  constructor(){
    super();
    console.log("授權(quán)異常構(gòu)造函數(shù)初始化"+new Date().toISOString());
  }
  catch(exception: AuthException, host: ArgumentsHost) {
    exception.exceptionCode=40002;
    console.log("授權(quán)異常執(zhí)行"+new Date().toISOString());
    this.writeToClient(host,exception);
  }

}

針對(duì)未授權(quán)異常處理類(lèi),進(jìn)行幾點(diǎn)說(shuō)明:

  1. 增加了Catch注解,只捕獲Authexception的異常,其他類(lèi)型的異常此類(lèi)不進(jìn)行處理
  2. 繼承自定義異常處理類(lèi)Baseexceptionfilter

應(yīng)用范圍

異常處理類(lèi)可應(yīng)用于method、controller、全局,甚至同一個(gè)Controller可以定義多個(gè)自定義異常類(lèi)

import { Controller, ForbiddenException, Get, HttpException, HttpStatus, UseFilters } from '@nestjs/common';
import { AppService } from './app.service';
import { AuthException } from './exceptions/auth.exception';
import { BusinessException } from './exceptions/business.exception';
import { UnCauhtException } from './exceptions/uncauht.exception';
import { AuthExceptionFilter } from './filters/auth.exception.filter';
import { BusinessExceptionFilter } from './filters/business.exception.filter';


/**
 * 帶有單個(gè)路由的基本控制器示例ff
 */
@UseFilters(AuthExceptionFilter,BusinessExceptionFilter)
@Controller()
export class AppController {
 constructor(private readonly appService: AppService) {}

 @Get()
 getHello(): string {
  //throw new Error("666");
  throw new BusinessException("自定義異常",HttpStatus.OK);
  throw new AuthException();
  throw new HttpException("自定義異常",HttpStatus.FORBIDDEN);
  return this.appService.getHello();
 }

 @Get("name")
 getName():string
 {
  return "guozhiqi";
 }
}

幾點(diǎn)說(shuō)明:

  1. 我們使用Usefilters注解進(jìn)行異常過(guò)濾器的添加
  2. 我們?cè)贏(yíng)ppcontroller中定義了兩種不同類(lèi)型的自定義異常處理類(lèi)
  3. 也就是我們Appcontroller中拋出的異常,只要是我們定義的這兩種,那么都可以被正常處理。

幾點(diǎn)疑問(wèn)

Usefitlers中我們自定義的異常處理類(lèi)會(huì)初始化幾次?
答案:我們通過(guò)類(lèi)型注冊(cè)到Appcontroller的自定義異常類(lèi)只會(huì)在程序初始化的時(shí)候初始化一次。也就是說(shuō)程序啟動(dòng)之后,每個(gè)

controller、每個(gè)method定義了哪些異常處理類(lèi)都已經(jīng)確定。
如果我們捕獲到異常,但不進(jìn)行任何處理,會(huì)發(fā)生什么?
答案:如果我們的異常處理方法什么也不做,那么恭喜你,會(huì)成功的將瀏覽器請(qǐng)求hang死,因?yàn)楫惓N刺幚?,那么瀏覽器會(huì)一直得不到響應(yīng)。

多個(gè)異常之間的處理順序如何?
答案:如果多個(gè)異常處理均可以捕獲到該異常,那么只有第一個(gè)有效,也就是說(shuō)異常處理類(lèi)和 中間件不同,異常處理類(lèi)只能其中一個(gè)處理,而中間件需要都進(jìn)行處理。

Nestjs的@Usefilters 像誰(shuí)?
首先從JS角度來(lái)看,像Angular,如果往后端看,最像Spring。 

Nestjs的異常處理并不復(fù)雜,復(fù)雜的是需要我們針對(duì)不同類(lèi)型的異常進(jìn)行處理,提取異常的共性。

參考文檔:docs.nestjs.cn

到此這篇關(guān)于nestjs中異常過(guò)濾器Exceptionfilter的具體使用的文章就介紹到這了,更多相關(guān)nest 異常過(guò)濾器Exceptionfilter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論