Skip to content

Commit

Permalink
fix(backend): catch prisma error globally
Browse files Browse the repository at this point in the history
  • Loading branch information
tericcabrel committed Jul 12, 2024
1 parent a5d7623 commit 1d025df
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 3 deletions.
5 changes: 5 additions & 0 deletions .changeset/wet-yaks-knock.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@snipcode/backend': patch
---

Catch Prisma technical error and return user friendly message
45 changes: 42 additions & 3 deletions apps/backend/src/configs/exception.filter.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,36 @@
import { ArgumentsHost, Catch } from '@nestjs/common';
import { AbstractHttpAdapter, BaseExceptionFilter } from '@nestjs/core';
import { GqlArgumentsHost, GqlContextType } from '@nestjs/graphql';
import {
PrismaClientInitializationError,
PrismaClientKnownRequestError,
PrismaClientRustPanicError,
PrismaClientUnknownRequestError,
PrismaClientValidationError,
} from '@prisma/client/runtime/library';
import { isAppError } from '@snipcode/utils';
import { Response } from 'express';
import { GraphQLError } from 'graphql';

import { INTERNAL_SERVER_ERROR } from '../utils/constants';

type PrismaError =
| PrismaClientInitializationError
| PrismaClientKnownRequestError
| PrismaClientRustPanicError
| PrismaClientUnknownRequestError
| PrismaClientValidationError;

const isPrismaError = (error: unknown): error is PrismaError => {
return (
error instanceof PrismaClientInitializationError ||
error instanceof PrismaClientKnownRequestError ||
error instanceof PrismaClientRustPanicError ||
error instanceof PrismaClientUnknownRequestError ||
error instanceof PrismaClientValidationError
);
};

@Catch()
export class ApplicationExceptionFilter extends BaseExceptionFilter {
constructor(httpAdapter: AbstractHttpAdapter) {
Expand All @@ -22,18 +48,31 @@ export class ApplicationExceptionFilter extends BaseExceptionFilter {
},
originalError: exception,
});
} else if (isPrismaError(exception)) {
throw new GraphQLError(INTERNAL_SERVER_ERROR, {
extensions: {
code: 'DATABASE_ERROR',
},
});
}
} else {
if (isAppError(exception)) {
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();
const ctx = host.switchToHttp();
const response = ctx.getResponse<Response>();

if (isAppError(exception)) {
response.status(400).json({
code: exception.code,
message: exception.message,
timestamp: new Date().toISOString(),
});
} else if (isPrismaError(exception)) {
response.status(500).json({
code: 'DATABASE_ERROR',
message: INTERNAL_SERVER_ERROR,
timestamp: new Date().toISOString(),
});
}

super.catch(exception, host);
}
}
Expand Down
2 changes: 2 additions & 0 deletions apps/backend/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ export const AUTH_USER_NOT_FOUND_CODE = 'AUTH_USER_NOT_FOUND';
export const AUTH_SUCCESS_URL = (webAuthSuccessUrl: string, sessionToken: string): string => {
return `${webAuthSuccessUrl}?token=${sessionToken}`;
};

export const INTERNAL_SERVER_ERROR = 'An internal error occurred, please try again later.';

0 comments on commit 1d025df

Please sign in to comment.