portal

  • Online demo account: guest, password: 123456
  • The source address

This chapter content

  1. Nest installation and error handling
  2. Customize the data return format
  3. Custom exception handling and error codes

The installation

Make sure you have node.js installed on your operating system (>= 10.13.0)

The local environment

$ node -v
v14.15.4
$ npm -v
6.14.11
Copy the code

Install the device in the CLI

$ npm i -g @nestjs/cli 
Copy the code

Initialize the project

$ nest new project-name
Copy the code

The project-name directory is created, the Node module and some other boilerplate are installed, and a SRC directory containing several core files is created

SRC ├── app.controller.ts ├── app.module.ts ├─ main.tsCopy the code

Run the project

$ npm run start
Copy the code

Something amazing happens, and it’s a bunch of mistakes

Don’t panic if you get a mistake. Check out a dating website:./node_modules/tapable

The Tapable library has been updated, and the webpack version has been updated as well. At least we found a solution.

Order one to go

$NPM I @types/[email protected] $NPM I [email protected]Copy the code

Run again start successfully, the browser input: http://localhost:3000/

Hello world! Charming as ever!

User modules

Whatever your business needs, you can create a user module first. Create a folder called modules under SRC and use Nest CLI to generate a user module, controller, and service

$ nest g mo modules/user
$ nest g co modules/user
$ nest g s modules/user
Copy the code

Write the following code to user.controller.ts

import { Controller, Get } from '@nestjs/common';

@Controller('user')
export class UserController {
  @Get('sayhi')
  async sayhi(): Promise<string> {
    return 'Hello world'; }}Copy the code

To run the project, the use of API debugging tools visit: http://localhost:3000/user/sayhi, in line with our expectations

The data format

In real projects, the API interface generally returns a fixed structure json object, similar

{
    "code":0."msg":"success"."data": {... }}Copy the code

Code is a custom service error code, such as no permission, the user name has been registered during the registration, etc. Create a libs folder in the SRC directory, and create an interceptor

$ nest g in libs/interceptors/data
Copy the code

Interceptor code

import {
  Injectable,
  NestInterceptor,
  CallHandler,
  ExecutionContext,
} from '@nestjs/common';
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs';
interface Response<T> {
  data: T;
}
@Injectable(a)export class TransformInterceptor<T>
  implements NestInterceptor<T.Response<T>> {
  intercept(
    context: ExecutionContext,
    next: CallHandler<T>,
  ): Observable<Response<T>> {
    return next.handle().pipe(
      map((data) = > {
        return {
          data: data ?? null.code: 0.message: 'success'}; })); }}Copy the code

Global registration in main.ts

import { NestFactory } from '@nestjs/core';
import { TransformInterceptor } from './libs/interceptors/data.interceptor';
import { AppModule } from './app.module';

async function bootstrap() {... app.useGlobalInterceptors(newTransformInterceptor()); . } bootstrap();Copy the code

Again to run the program, visit: http://localhost:3000/user/sayhi

{
    "data": "Hello world"."code": 0."message": "success"
}
Copy the code

Custom exception

In a real project, in many cases we need to interrupt the program, return an error message, and create a filter

$ nest g f libs/filters/http-exception
Copy the code

In the SRC /libs directory, create the enums directory, create the error-code-enum. Ts file, and put several error codes

export enum BusiErrorCode {
  TIMEOUT = -1.// System is busy
  SUCCESS = 0./ / success
  PARAM_ERROR = 10000.// The request parameter is incorrect
  NOT_FOUND = 10001.// The resource you are looking for does not exist
  UN_AUTHORIZED = 20000.// The user is not logged in
  AUTH_FORBIDDEN = 30000.// The user has no permissions
  PWD_ERROR = 40000.// The account or password is incorrect
}
Copy the code

Create the busi.exception.ts file in libs/filters directory

import { HttpException, HttpStatus } from '@nestjs/common';
import { BusiErrorCode } from '.. /enums/error-code-enum';

export class BusiException extends HttpException {
  private _code: BusiErrorCode;
  private _message: string;
  constructor(
    code: BusiErrorCode | number,
    message: string,
    statusCode: HttpStatus = HttpStatus.BAD_REQUEST,
  ) {
    super(message, statusCode);
    this._code = code;
    this._message = message;
  }

  getErrorCode(): BusiErrorCode {
    return this._code;
  }

  getErrorMessage(): string {
    return this._message; }}Copy the code

Code in the http-exception.filter.ts file

import {
  ArgumentsHost,
  Catch,
  ExceptionFilter,
  HttpException,
} from '@nestjs/common';
import { BusiException } from './busi.exception';

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

    let code, message;
    if (exception instanceof BusiException) {
      code = exception.getErrorCode();
      message = exception.getErrorMessage();
    } else {
      code = exception.getStatus();
      message = exception.message;
    }
    response.status(status).json({
      code,
      message,
      data: null.date: new Date().toLocaleDateString(),
      path: request.url, }); }}Copy the code

Global registration in main.ts

import { NestFactory } from '@nestjs/core';
import { TransformInterceptor } from './libs/interceptors/data.interceptor';
import { AppModule } from './app.module';

async function bootstrap() {... app.useGlobalFilters(newHttpExceptionFilter()); . } bootstrap();Copy the code

Modify user.controller.ts to include the code that triggers the exception

import { Controller, Get, HttpStatus } from '@nestjs/common';
import { BusiException } from '.. /.. /libs/filters/busi.exception';
import { BusiErrorCode } from '.. /.. /libs/enums/error-code-enum';

@Controller('user')
export class UserController {...@Get('exception')
  async exception(): Promise<string> {
    // Throw new BusiException(busierrorCode.not_found, 'default status code, default HTTP 400 error ');
    throw new BusiException(
      BusiErrorCode.NOT_FOUND,
      'Error: HTTP status is normal', HttpStatus.OK, ); }}Copy the code

To run the program, visit: http://localhost:3000/user/exception

It looks good. Next we’ll play around with TypeOrm and MySQL database.