feat: exceptions handlers (#2855)

* feat: wip exception handlers

* feat: exception capturer

* fix: rename exception-capturer into exception-handler

* fix: remove unused variable
This commit is contained in:
Jérémy M
2023-12-08 10:18:50 +01:00
committed by GitHub
parent 6c83953633
commit cf334ada0e
38 changed files with 983 additions and 340 deletions

View File

@ -1,56 +0,0 @@
import { ArgumentsHost, Catch, HttpException } from '@nestjs/common';
import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql';
import { TypeORMError } from 'typeorm';
import {
AuthenticationError,
BaseGraphQLError,
ForbiddenError,
} from 'src/filters/utils/graphql-errors.util';
const graphQLPredefinedExceptions = {
401: AuthenticationError,
403: ForbiddenError,
};
@Catch()
export class ExceptionFilter implements GqlExceptionFilter {
catch(exception: HttpException | TypeORMError, host: ArgumentsHost) {
if (host.getType<GqlContextType>() !== 'graphql') {
return null;
}
if (exception instanceof TypeORMError) {
const error = new BaseGraphQLError(
exception.name,
'INTERNAL_SERVER_ERROR',
);
error.stack = exception.stack;
error.extensions['response'] = exception.message;
return error;
} else if (exception instanceof HttpException) {
let error: BaseGraphQLError;
if (exception.getStatus() in graphQLPredefinedExceptions) {
error = new graphQLPredefinedExceptions[exception.getStatus()](
exception.message,
);
} else {
error = new BaseGraphQLError(
exception.message,
exception.getStatus().toString(),
);
}
error.stack = exception.stack;
error.extensions['response'] = exception.getResponse();
return error;
}
return exception;
}
}

View File

@ -0,0 +1,18 @@
import { Catch, Injectable } from '@nestjs/common';
import { GqlExceptionFilter } from '@nestjs/graphql';
import { ExceptionHandlerService } from 'src/integrations/exception-handler/exception-handler.service';
@Catch()
@Injectable()
export class GlobalExceptionFilter implements GqlExceptionFilter {
constructor(
private readonly exceptionHandlerService: ExceptionHandlerService,
) {}
catch(exception: unknown) {
this.exceptionHandlerService.captureException(exception);
return exception;
}
}

View File

@ -0,0 +1,42 @@
import { ArgumentsHost, Catch, HttpException } from '@nestjs/common';
import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql';
import {
AuthenticationError,
BaseGraphQLError,
ForbiddenError,
} from 'src/filters/utils/graphql-errors.util';
const graphQLPredefinedExceptions = {
401: AuthenticationError,
403: ForbiddenError,
};
@Catch(HttpException)
export class HttpExceptionFilter
implements GqlExceptionFilter<HttpException, BaseGraphQLError | null>
{
catch(exception: HttpException, host: ArgumentsHost) {
if (host.getType<GqlContextType>() !== 'graphql') {
return null;
}
let error: BaseGraphQLError;
if (exception.getStatus() in graphQLPredefinedExceptions) {
error = new graphQLPredefinedExceptions[exception.getStatus()](
exception.message,
);
} else {
error = new BaseGraphQLError(
exception.message,
exception.getStatus().toString(),
);
}
error.stack = exception.stack;
error.extensions['response'] = exception.getResponse();
return error;
}
}

View File

@ -0,0 +1,24 @@
import { ArgumentsHost, Catch } from '@nestjs/common';
import { GqlContextType, GqlExceptionFilter } from '@nestjs/graphql';
import { TypeORMError } from 'typeorm';
import { BaseGraphQLError } from 'src/filters/utils/graphql-errors.util';
@Catch(TypeORMError)
export class TypeOrmExceptionFilter
implements GqlExceptionFilter<TypeORMError, BaseGraphQLError | null>
{
catch(exception: TypeORMError, host: ArgumentsHost) {
if (host.getType<GqlContextType>() !== 'graphql') {
return null;
}
const error = new BaseGraphQLError(exception.name, 'INTERNAL_SERVER_ERROR');
error.stack = exception.stack;
error.extensions['response'] = exception.message;
return error;
}
}