如何处理 NestJS 中的 TypeORM 错误?
How can I handle TypeORM error in NestJS?
我想创建一个自定义异常过滤器来处理不同类型的 TypeORM 错误。我查过 TypeORM error classes, and it seems like there's no such thing in TypeORM like MongoError.
我想做一些类似于 的东西,这是我目前所做的。
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);
}
}
如果我需要捕获另一个错误,例如 EntityNotFoundError
,我必须编写相同的代码,这是一项非常繁琐的任务。
如果我能像下面这样通过单个过滤器处理错误就好了。有什么想法吗?
@Catch(TypeORMError)
export class EntityNotFoundExceptionFilter implements ExceptionFilter {
catch(exception: MongoError, host: ArgumentsHost) {
switch (exception.code) {
case some error code:
// handle error
}
}
}
在 documentation 中,它说:
The @Catch()
decorator may take a single parameter, or a
comma-separated list. This lets you set up the filter for several
types of exceptions at once.
所以在你的情况下你可以这样写:
@Catch(QueryFailedError, EntityNotFoundError)
为了处理不同类型的 TypeOrm 错误,如果异常构造函数匹配任何 TypeOrm 错误(来自 node_modules\typeorm\error),您可以切换/大小写异常构造函数。此外,(exception as any).code 将提供发生的实际数据库错误。注意 @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;
}
注意:从 typeorm
的新版本开始,EntityNotFoundError
和 CannotCreateEntityIdMapError
的导入将如下所示
import { QueryFailedError } from 'typeorm';
import { EntityNotFoundError } from 'typeorm/error/EntityNotFoundError';
import { CannotCreateEntityIdMapError } from 'typeorm/error/CannotCreateEntityIdMapError';
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);
}
}
我想创建一个自定义异常过滤器来处理不同类型的 TypeORM 错误。我查过 TypeORM error classes, and it seems like there's no such thing in TypeORM like MongoError.
我想做一些类似于
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);
}
}
如果我需要捕获另一个错误,例如 EntityNotFoundError
,我必须编写相同的代码,这是一项非常繁琐的任务。
如果我能像下面这样通过单个过滤器处理错误就好了。有什么想法吗?
@Catch(TypeORMError)
export class EntityNotFoundExceptionFilter implements ExceptionFilter {
catch(exception: MongoError, host: ArgumentsHost) {
switch (exception.code) {
case some error code:
// handle error
}
}
}
在 documentation 中,它说:
The
@Catch()
decorator may take a single parameter, or a comma-separated list. This lets you set up the filter for several types of exceptions at once.
所以在你的情况下你可以这样写:
@Catch(QueryFailedError, EntityNotFoundError)
为了处理不同类型的 TypeOrm 错误,如果异常构造函数匹配任何 TypeOrm 错误(来自 node_modules\typeorm\error),您可以切换/大小写异常构造函数。此外,(exception as any).code 将提供发生的实际数据库错误。注意 @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;
}
注意:从 typeorm
的新版本开始,EntityNotFoundError
和 CannotCreateEntityIdMapError
的导入将如下所示
import { QueryFailedError } from 'typeorm';
import { EntityNotFoundError } from 'typeorm/error/EntityNotFoundError';
import { CannotCreateEntityIdMapError } from 'typeorm/error/CannotCreateEntityIdMapError';
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);
}
}