nestjs中異常過濾器Exceptionfilter的具體使用
說(shuō)起Nestjs的異常過濾器,不能不提.Net的全局過濾器Filter,功能那是相當(dāng)?shù)膹?qiáng)悍,用理論話說(shuō)叫AOP 面向切面編程,可謂方便了太多需要異常處理的場(chǎng)景。說(shuō)回Nestjs的異常過濾器,實(shí)現(xiàn)類似的功能,采用相似的處理方式,只不過一個(gè)面向C#,一個(gè)面向Nodejs,很榮幸的我,在兩個(gè)框架都找到了類似的東西。
面向切面編程AOP,是一種類似于編程規(guī)范的東東,同門師兄弟有叫面向接口編程、SOLID原則等等。
Nestjs的異常處理
默認(rèn)異常處理
Nestjs內(nèi)置了默認(rèn)的全局異常過濾器,處理能夠轉(zhuǎn)換成Httpexception的異常。
如果是Httpexception或其子類異常,那么會(huì)返回該異常的JSON格式:
{"exceptionCode":40005,"message":"自定義異常","path":"/"}
如果不是Httpexception或其子類異常,那么會(huì)返回:
{"statusCode":500,"message":"Internal server error"}
由于Nestjs采用了內(nèi)置的默認(rèn)異常處理,因此不會(huì)出現(xiàn)由于出現(xiàn)未捕獲的異常導(dǎo)致程序崩潰。
自定義異常過濾器處理
由于內(nèi)置異常處理返回值格式無(wú)法調(diào)整,因此自定義異常就顯得又為正常。自定義異??梢允狗祷禺惓P畔⒆远x,且可以增加自定義異常編碼,方便客戶端人員根據(jù)異常編碼進(jìn)行不同的展示。
如何自定義異常?
不重復(fù)造輪子是程序員的自我約束,首先我們新建我們自己的異?;悾?/p>
import { HttpException } from "@nestjs/common";
/**
* 定義基礎(chǔ)異常類
*
* @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)異常類型,其中增加了自定義異常代碼:
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)異常,首先新建自定義異常處理基類,請(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";
/**
* 異常基礎(chǔ)類過濾器
*
* @export
* @class BaseExceptionFilter
* @implements {ExceptionFilter<BaseException>}
*/
export abstract class BaseExceptionFilter implements ExceptionFilter<BaseException>
{
/**
* 異常類捕獲
*
* @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>();
}
/**
* 寫入異常信息到客戶端
*
* @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)異常處理類,進(jìn)行幾點(diǎn)說(shuō)明:
- 增加了Catch注解,只捕獲Authexception的異常,其他類型的異常此類不進(jìn)行處理
- 繼承自定義異常處理類Baseexceptionfilter
應(yīng)用范圍
異常處理類可應(yīng)用于method、controller、全局,甚至同一個(gè)Controller可以定義多個(gè)自定義異常類
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ō)明:
- 我們使用Usefilters注解進(jìn)行異常過濾器的添加
- 我們?cè)贏ppcontroller中定義了兩種不同類型的自定義異常處理類
- 也就是我們Appcontroller中拋出的異常,只要是我們定義的這兩種,那么都可以被正常處理。
幾點(diǎn)疑問
Usefitlers中我們自定義的異常處理類會(huì)初始化幾次?
答案:我們通過類型注冊(cè)到Appcontroller的自定義異常類只會(huì)在程序初始化的時(shí)候初始化一次。也就是說(shuō)程序啟動(dòng)之后,每個(gè)
controller、每個(gè)method定義了哪些異常處理類都已經(jīng)確定。
如果我們捕獲到異常,但不進(jìn)行任何處理,會(huì)發(fā)生什么?
答案:如果我們的異常處理方法什么也不做,那么恭喜你,會(huì)成功的將瀏覽器請(qǐng)求hang死,因?yàn)楫惓N刺幚?,那么瀏覽器會(huì)一直得不到響應(yīng)。
多個(gè)異常之間的處理順序如何?
答案:如果多個(gè)異常處理均可以捕獲到該異常,那么只有第一個(gè)有效,也就是說(shuō)異常處理類和 中間件不同,異常處理類只能其中一個(gè)處理,而中間件需要都進(jìn)行處理。
Nestjs的@Usefilters 像誰(shuí)?
首先從JS角度來(lái)看,像Angular,如果往后端看,最像Spring。
Nestjs的異常處理并不復(fù)雜,復(fù)雜的是需要我們針對(duì)不同類型的異常進(jìn)行處理,提取異常的共性。
參考文檔:docs.nestjs.cn
到此這篇關(guān)于nestjs中異常過濾器Exceptionfilter的具體使用的文章就介紹到這了,更多相關(guān)nest 異常過濾器Exceptionfilter內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- 利用Dockerfile優(yōu)化Nestjs構(gòu)建鏡像大小詳情
- Dapr+NestJs編寫Pub及Sub裝飾器實(shí)戰(zhàn)示例
- Docker?Compose+Nestjs構(gòu)建Dapr?Redis發(fā)布訂閱分布式應(yīng)用
- NestJS+Redis實(shí)現(xiàn)緩存步驟詳解
- nestjs返回給前端數(shù)據(jù)格式的封裝實(shí)現(xiàn)
- NestJs使用Mongoose對(duì)MongoDB操作的方法
- NestJs 靜態(tài)目錄配置詳解
- 使用NestJS開發(fā)Node.js應(yīng)用的方法
- nestjs搭建HTTP與WebSocket服務(wù)詳細(xì)過程
相關(guān)文章
基于Node.js模板引擎教程-jade速學(xué)與實(shí)戰(zhàn)1
下面小編就為大家?guī)?lái)一篇基于Node.js模板引擎教程-jade速學(xué)與實(shí)戰(zhàn)1。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2017-09-09
node.js項(xiàng)目如何創(chuàng)建websocket模塊
這篇文章主要介紹了node.js項(xiàng)目如何創(chuàng)建websocket模塊問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-09-09
Node.js基礎(chǔ)入門之模塊與npm包管理器使用詳解
Node.js是一個(gè)基于Chrome?V8引擎的JavaScript運(yùn)行時(shí)。類似于Java中的JRE,.Net中的CLR。本文將詳細(xì)為大家介紹Node.js中的模塊與npm包管理器的使用,需要的可以參考一下2022-03-03
node作為中間服務(wù)層如何發(fā)送請(qǐng)求(發(fā)送請(qǐng)求的實(shí)現(xiàn)方法詳解)
node作為中間服務(wù)層如何發(fā)送請(qǐng)求?下面小編就為大家分享一下發(fā)送請(qǐng)求的實(shí)現(xiàn)方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助2018-01-01
Node.js中使用Buffer編碼、解碼二進(jìn)制數(shù)據(jù)詳解
這篇文章主要介紹了Node.js中使用Buffer編碼、解碼二進(jìn)制數(shù)據(jù)詳解,Buffer支持ascii、utf8、ucs2、base64等編碼格式,需要的朋友可以參考下2014-08-08
詳解webpack打包nodejs項(xiàng)目(前端代碼)
這篇文章主要介紹了webpack打包nodejs項(xiàng)目(前端代碼),小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-09-09
nodeJS(express4.x)+vue(vue-cli)構(gòu)建前后端分離實(shí)例(帶跨域)
這篇文章主要介紹了nodeJS(express4.x)+vue(vue-cli)構(gòu)建前后端分離實(shí)例(帶跨域) ,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Windows系統(tǒng)下Node.js的簡(jiǎn)單入門教程
這篇文章主要介紹了Windows系統(tǒng)下Node.js的簡(jiǎn)單入門教程,Node.js是用于后端編程的JavaScript框架,需要的朋友可以參考下2015-06-06
nodejs微信開發(fā)之授權(quán)登錄+獲取用戶信息
這篇文章主要介紹了nodejs微信開發(fā)之授權(quán)登錄+獲取用戶信息,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2019-03-03

