Specific use of exception filter Exceptionfilter in nestjs

Specific use of exception filter Exceptionfilter in nestjs

Speaking of Nestjs exception filter, we have to mention .Net's global filter, which is quite powerful. In theory, it is called AOP aspect-oriented programming, which facilitates too many scenarios that require exception handling. Back to the exception filter of Nestjs, it implements similar functions and adopts similar processing methods, but one is for C# and the other is for Nodejs. Fortunately, I have found similar things in both frameworks.

Aspect-Oriented Programming (AOP) is something similar to a programming specification. Its fellow practitioners also call it interface-oriented programming, SOLID principles, and so on.

Exception handling in Nestjs

Default exception handling

Nestjs has a built-in default global exception filter that handles exceptions that can be converted into HttpException.

If it is an HttpException or its subclass exception, the JSON format of the exception will be returned:

{"exceptionCode":40005,"message":"Custom exception","path":"/"}

If it is not an HttpException or its subclass exception, it will return:

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

Since Nestjs uses built-in default exception handling, there will be no program crash due to uncaught exceptions.

Custom exception filter handling

Since the return value format of built-in exception handling cannot be adjusted, custom exceptions are normal. Custom exceptions can customize the returned exception information and add custom exception codes to facilitate client personnel to display differently according to the exception codes.

How to customize exceptions?

Not reinventing the wheel is a programmer's self-restraint. First, we create our own exception base class:

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

/**
 * Define the base exception class *
 * @export
 * @class BaseException
 * @extends {HttpException}
 */
export class BaseException extends HttpException {

  /**
   * Creates an instance of BaseException.
   * @param {number} exceptionCode custom exception number* @param {string} errorMessage prompt message* @param {number} statusCode status code* @memberof BaseException
   */
  constructor(public exceptionCode: number, public errorMessage: string, public statusCode: number) {
    super({ exceptionCode: exceptionCode, errorMessage: errorMessage }, statusCode);
  }

  /**
   * Get custom exception code *
   * @return {*}
   * @memberof BaseException
   */
  getExceptionCode(): number {
    return this.exceptionCode;
  }

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

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

Then we create a new unauthorized exception type, which adds a custom exception code:

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

export class UnCauhtException extends BaseException {
  constructor() {
    super(40000, "System operation abnormality, please contact the administrator!", HttpStatus.FORBIDDEN);
  }
}

Now that we have created a custom exception, we need to handle unauthorized exceptions. First, create a new custom exception handling base class. Please note that we use Express here:

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";

/**
 * Abnormal base class filter *
 * @export
 * @class BaseExceptionFilter
 * @implements {ExceptionFilter<BaseException>}
 */
export abstract class BaseExceptionFilter implements ExceptionFilter<BaseException>
{
  /**
   *Exception class capture*
   * @abstract
   * @param {BaseException} exception
   * @param {ArgumentsHost} host
   * @memberof BaseExceptionFilter
   */
  abstract catch(exception: BaseException, host: ArgumentsHost);

  /**
   * Get http request context parameters *
   * @protected
   * @param {ArgumentsHost} host
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getHttpContext(host: ArgumentsHost) {
    return host.switchToHttp();
  }

  /**
   * Get http response parameters *
   * @protected
   * @param {HttpArgumentsHost} httpContext
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getResponse(httpContext: HttpArgumentsHost): Response {
    return httpContext.getResponse<Response>();
  }

  /**
   * Get http request parameters *
   * @protected
   * @param {HttpArgumentsHost} httpContext
   * @return {*}
   * @memberof BaseExceptionFilter
   */
  protected getRequest(httpContext: HttpArgumentsHost): Request {
    return httpContext.getRequest<Request>();
  }

  /**
   * Write exception information to the client *
   * @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: "Unhandled exception",
        path: this.getRequest(ctx).url
      });
    }

  }
}

Create a new unauthorized exception handler:

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("Authorization exception constructor initialization"+new Date().toISOString());
  }
  catch(exception: AuthException, host: ArgumentsHost) {
    exception.exceptionCode=40002;
    console.log("Authorization exception execution"+new Date().toISOString());
    this.writeToClient(host,exception);
  }

}

Here are some explanations for the unauthorized exception handling class:

  1. Added Catch annotation to catch only Authexception exceptions, and other types of exceptions are not processed
  2. Inherit the custom exception handling class Baseexceptionfilter

Application

Exception handling classes can be applied to methods, controllers, or globally. Even the same Controller can define multiple custom exception classes.

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';


/**
 * Basic controller example with a single route
 */
@UseFilters(AuthExceptionFilter,BusinessExceptionFilter)
@Controller()
export class AppController {
 constructor(private readonly appService: AppService) {}

 @Get()
 getHello(): string {
  //throw new Error("666");
  throw new BusinessException("custom exception",HttpStatus.OK);
  throw new AuthException();
  throw new HttpException("custom exception",HttpStatus.FORBIDDEN);
  return this.appService.getHello();
 }

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

A few notes:

  1. We use the Usefilters annotation to add exception filters
  2. We define two different types of custom exception handling classes in Appcontroller
  3. That is, the exceptions thrown in our Appcontroller can be handled normally as long as they are the two types we defined.

A few questions

How many times will our custom exception handling class in Usefitlers be initialized?
Answer: The custom exception class that we register to AppController by type will only be initialized once when the program is initialized. That is to say, after the program starts, each

The exception handling classes defined by the controller and each method have been determined.
What happens if we catch the exception but don't do anything with it?
Answer: If our exception handling method does nothing, then congratulations, you will successfully hang the browser request, because the exception is not handled, so the browser will not get a response.

What is the order in which multiple exceptions are handled?
Answer: If multiple exception handlers can catch the exception, only the first one is valid. That is to say, the exception handling class is different from the middleware. Only one of the exception handling classes can handle it, while the middleware needs to handle both.

Who is Nestjs's @Usefilters like?
First of all, from the JS perspective, it is like Angular. If you look at the backend, it is most like Spring.

Nestjs's exception handling is not complicated. What is complicated is that we need to handle different types of exceptions and extract the commonalities of the exceptions.

Reference document: docs.nestjs.cn

This is the end of this article about the specific use of the exception filter Exceptionfilter in nestjs. For more related nest exception filter Exceptionfilter content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • How to use ExceptionFilter in .Net Core
  • asp.net core MVC global filter ExceptionFilter filter (1)

<<:  Detailed introduction to nobody user and nologin in Unix/Linux system

>>:  Simple implementation of ignoring foreign key constraints when deleting MySQL tables

Recommend

Detailed steps to install Nginx on Linux

1. Nginx installation steps 1.1 Official website ...

Detailed example code of mysql batch insert loop

background A few days ago, when I was doing pagin...

IIS configuration of win server 2019 server and simple publishing of website

1. First remotely connect to the server 2. Open S...

Detailed explanation of Linux commands and file search

1. Perform file name search which (search for ...

Detailed explanation of React event binding

1. What is In react applications, event names are...

Nginx load balancing algorithm and failover analysis

Overview Nginx load balancing provides upstream s...

Introduction to who command examples in Linux

About who Displays users logged into the system. ...

How to implement logic reuse with Vue3 composition API

Composition API implements logic reuse steps: Ext...

MySQL Full-text Indexing Guide

Full-text indexing requires special query syntax....

How to operate the check box in HTML page

Checkboxes are very common on web pages. Whether ...

Graphic tutorial on configuring nginx file server in windows 10 system

Download the Windows version of Nginx from the Ng...

How to use squid to build a proxy server for http and https

When we introduced nginx, we also used nginx to s...

Solve the problem of docker pull image error

describe: Install VM under Windows 10, run Docker...