简体   繁体   English

如何处理 NestJS 中的 TypeORM 错误?

[英]How can I handle TypeORM error in NestJS?

I'd like to create a custom exception filter that handles different kinds of TypeORM errors.我想创建一个自定义异常过滤器来处理不同类型的 TypeORM 错误。 I've looked up the TypeORM error classes , and it seems like there's no such thing in TypeORM like MongoError .我查看了TypeORM 错误类,似乎 TypeORM 中没有像MongoError这样的东西。

I wanted to make something similar to 1FpGLLjZSZMx6k's answer , and here's what I've done so far.我想做一些类似于1FpGLLjZSZMx6k 的答案的东西,这就是我到目前为止所做的。

import { QueryFailedError } from 'typeorm';

@Catch(QueryFailedError)
export class QueryFailedExceptionFilter implements ExceptionFilter {
  catch(exception: QueryFailedError, host: ArgumentsHost) {
    const context = host.switchToHttp();
    const response = context.getResponse<Response>();
    const request = context.getRequest<Request>();
    const { url } = request;
    const { name } = exception;
    const errorResponse = {
      path: url,
      timestamp: new Date().toISOString(),
      message: name,
    };

    response.status(HttpStatus.BAD_REQUEST).json(errorResponse);
  }
}

If I need to catch another error for instance, EntityNotFoundError , I have to write the same code which is a very cumbersome task to do it.如果我需要捕获另一个错误,例如EntityNotFoundError ,我必须编写相同的代码,这是一项非常繁琐的任务。

It would be nice if I could handle errors by a single filter like below.如果我可以通过如下所示的单个过滤器处理错误,那就太好了。 Any ideas?有任何想法吗?

@Catch(TypeORMError)
export class EntityNotFoundExceptionFilter implements ExceptionFilter {
  catch(exception: MongoError, host: ArgumentsHost) {
    switch (exception.code) {
      case some error code:
        // handle error
    }
  }
}

In the documentation , it says:文档中,它说:

The @Catch() decorator may take a single parameter, or a comma-separated list . @Catch()装饰器可以采用单个参数或逗号分隔的列表 This lets you set up the filter for several types of exceptions at once.这使您可以一次为多种类型的异常设置过滤器。

So in your case you could write:所以在你的情况下,你可以写:

@Catch(QueryFailedError, EntityNotFoundError)

To handle different kinds of TypeOrm errors, you can switch / case the exception constructor if it matches any TypeOrm error (from node_modules\typeorm\error).要处理不同类型的 TypeOrm 错误,如果异常构造函数匹配任何 TypeOrm 错误(来自 node_modules\typeorm\error),您可以切换/ case。 Additionally, the (exception as any).code will provide the actual database error that occured.此外, (exception as any).code 将提供发生的实际数据库错误。 Notice the @catch() decorator is empty in order to catch all error types.注意 @catch() 装饰器是空的,以便捕获所有错误类型。

import { ArgumentsHost, Catch, ExceptionFilter, HttpException, HttpStatus, Logger } from '@nestjs/common';
import { Request, Response } from 'express';
import { QueryFailedError, EntityNotFoundError, CannotCreateEntityIdMapError } from 'typeorm';
import { GlobalResponseError } from './global.response.error';

@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
    catch(exception: unknown, host: ArgumentsHost) {
        const ctx = host.switchToHttp();
        const response = ctx.getResponse<Response>();
        const request = ctx.getRequest<Request>();
        let message = (exception as any).message.message;
        let code = 'HttpException';

        Logger.error(message, (exception as any).stack, `${request.method} ${request.url}`);

        let status = HttpStatus.INTERNAL_SERVER_ERROR;
        
        switch (exception.constructor) {
            case HttpException:
                status = (exception as HttpException).getStatus();
                break;
            case QueryFailedError:  // this is a TypeOrm error
                status = HttpStatus.UNPROCESSABLE_ENTITY
                message = (exception as QueryFailedError).message;
                code = (exception as any).code;
                break;
            case EntityNotFoundError:  // this is another TypeOrm error
                status = HttpStatus.UNPROCESSABLE_ENTITY
                message = (exception as EntityNotFoundError).message;
                code = (exception as any).code;
                break;
            case CannotCreateEntityIdMapError: // and another
                status = HttpStatus.UNPROCESSABLE_ENTITY
                message = (exception as CannotCreateEntityIdMapError).message;
                code = (exception as any).code;
                break;
            default:
                status = HttpStatus.INTERNAL_SERVER_ERROR
        }

        response.status(status).json(GlobalResponseError(status, message, code, request));
    }
}


import { Request } from 'express';
import { IResponseError } from './response.error.interface';

export const GlobalResponseError: (statusCode: number, message: string, code: string, request: Request) => IResponseError = (
    statusCode: number,
    message: string,
    code: string,
    request: Request
): IResponseError => {
    return {
        statusCode: statusCode,
        message,
        code,
        timestamp: new Date().toISOString(),
        path: request.url,
        method: request.method
    };
};


export interface IResponseError {
    statusCode: number;
    message: string;
    code: string;
    timestamp: string;
    path: string;
    method: string;
}

 import { ArgumentsHost, Catch, ExceptionFilter } from '@nestjs/common'; import { TypeORMError } from 'typeorm'; import { ErrorMessage } from '../error.interface'; @Catch(TypeORMError) export class TypeOrmFilter implements ExceptionFilter { catch(exception: TypeORMError, host: ArgumentsHost) { const response = host.switchToHttp().getResponse(); let message: string = (exception as TypeORMError).message; let code: number = (exception as any).code; const customResponse: ErrorMessage = { status: 500, message: 'Something Went Wrong', type: 'Internal Server Error', errors: [{ code: code, message: message }], errorCode: 300, timestamp: new Date().toISOString(), }; response.status(customResponse.status).json(customResponse); } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM