diff --git a/src/errors/error-mapping.ts b/src/errors/error-mapping.ts new file mode 100644 index 000000000..59967bf54 --- /dev/null +++ b/src/errors/error-mapping.ts @@ -0,0 +1,89 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import { + ArgumentsHost, + BadRequestException, + ConflictException, + InternalServerErrorException, + NotFoundException, + UnauthorizedException, +} from '@nestjs/common'; +import { HttpException } from '@nestjs/common/exceptions/http.exception'; +import { BaseExceptionFilter } from '@nestjs/core'; + +import { + buildHttpExceptionObject, + HttpExceptionObject, +} from './http-exception-object'; + +type HttpExceptionConstructor = (object: HttpExceptionObject) => HttpException; + +const mapOfHedgeDocErrorsToHttpErrors: Map = + new Map([ + ['NotInDBError', (object): HttpException => new NotFoundException(object)], + [ + 'AlreadyInDBError', + (object): HttpException => new ConflictException(object), + ], + [ + 'ForbiddenIdError', + (object): HttpException => new BadRequestException(object), + ], + ['ClientError', (object): HttpException => new BadRequestException(object)], + [ + 'PermissionError', + (object): HttpException => new UnauthorizedException(object), + ], + [ + 'TokenNotValidError', + (object): HttpException => new UnauthorizedException(object), + ], + [ + 'TooManyTokensError', + (object): HttpException => new BadRequestException(object), + ], + [ + 'PermissionsUpdateInconsistentError', + (object): HttpException => new BadRequestException(object), + ], + [ + 'MediaBackendError', + (object): HttpException => new InternalServerErrorException(object), + ], + [ + 'PrimaryAliasDeletionForbiddenError', + (object): HttpException => new BadRequestException(object), + ], + [ + 'InvalidCredentialsError', + (object): HttpException => new UnauthorizedException(object), + ], + [ + 'NoLocalIdentityError', + (object): HttpException => new BadRequestException(object), + ], + ]); + +export class ErrorExceptionMapping extends BaseExceptionFilter { + catch(error: Error, host: ArgumentsHost): void { + super.catch(ErrorExceptionMapping.transformError(error), host); + } + + private static transformError(error: Error): Error { + const httpExceptionConstructor = mapOfHedgeDocErrorsToHttpErrors.get( + error.name, + ); + if (httpExceptionConstructor === undefined) { + // We don't know how to map this error and just leave it be + return error; + } + const httpExceptionObject = buildHttpExceptionObject( + error.name, + error.message, + ); + return httpExceptionConstructor(httpExceptionObject); + } +} diff --git a/src/errors/http-exception-object.ts b/src/errors/http-exception-object.ts new file mode 100644 index 000000000..2f9a399ce --- /dev/null +++ b/src/errors/http-exception-object.ts @@ -0,0 +1,20 @@ +/* + * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ + +export interface HttpExceptionObject { + name: string; + message: string; +} + +export function buildHttpExceptionObject( + name: string, + message: string, +): HttpExceptionObject { + return { + name: name, + message: message, + }; +}