diff --git a/src/articles/articles.controller.ts b/src/articles/articles.controller.ts index 1085cf9..5cc6aab 100644 --- a/src/articles/articles.controller.ts +++ b/src/articles/articles.controller.ts @@ -1,4 +1,4 @@ -import { Controller, Get, Post, Body, Patch, Param, Delete, ParseIntPipe } from '@nestjs/common'; +import { Controller, Get, Post, Body, Patch, Param, Delete, NotFoundException, ParseIntPipe } from '@nestjs/common'; import { ArticlesService } from './articles.service'; import { CreateArticleDto } from './dto/create-article.dto'; import { UpdateArticleDto } from './dto/update-article.dto'; @@ -30,8 +30,12 @@ export class ArticlesController { @Get(':id') @ApiOkResponse({ type: ArticleEntity }) - findOne(@Param('id', ParseIntPipe) id: number) { - return this.articlesService.findOne(id); + async findOne(@Param('id', ParseIntPipe) id: number) { + const article = await this.articlesService.findOne(id) + if (!article) { + throw new NotFoundException(`Article with ${id} does not exist.`) + } + return article } @Patch(':id') diff --git a/src/main.ts b/src/main.ts index 0cfc89d..840caae 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,7 +1,8 @@ -import { NestFactory } from '@nestjs/core'; +import { HttpAdapterHost, NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { ValidationPipe } from '@nestjs/common' +import { PrismaClientExceptionFilter } from './prisma-client-exception/prisma-client-exception.filter'; async function bootstrap() { const app = await NestFactory.create(AppModule); @@ -17,6 +18,9 @@ async function bootstrap() { const document = SwaggerModule.createDocument(app, config) SwaggerModule.setup('api', app, document) + const { httpAdapter } = app.get(HttpAdapterHost) + app.useGlobalFilters(new PrismaClientExceptionFilter(httpAdapter)) + await app.listen(3000); } bootstrap(); diff --git a/src/prisma-client-exception/prisma-client-exception.filter.spec.ts b/src/prisma-client-exception/prisma-client-exception.filter.spec.ts new file mode 100644 index 0000000..22ae81d --- /dev/null +++ b/src/prisma-client-exception/prisma-client-exception.filter.spec.ts @@ -0,0 +1,7 @@ +import { PrismaClientExceptionFilter } from './prisma-client-exception.filter'; + +describe('PrismaClientExceptionFilter', () => { + it('should be defined', () => { + expect(new PrismaClientExceptionFilter()).toBeDefined(); + }); +}); diff --git a/src/prisma-client-exception/prisma-client-exception.filter.ts b/src/prisma-client-exception/prisma-client-exception.filter.ts new file mode 100644 index 0000000..015bf1a --- /dev/null +++ b/src/prisma-client-exception/prisma-client-exception.filter.ts @@ -0,0 +1,39 @@ +//src/prisma-client-exception.filter.ts + +import { ArgumentsHost, Catch, HttpStatus } from '@nestjs/common'; +import { BaseExceptionFilter } from '@nestjs/core'; +import { Prisma } from '@prisma/client'; +import { Response } from 'express'; + +@Catch(Prisma.PrismaClientKnownRequestError) +export class PrismaClientExceptionFilter extends BaseExceptionFilter { + catch(exception: Prisma.PrismaClientKnownRequestError, host: ArgumentsHost) { + console.error(exception.message); + const ctx = host.switchToHttp(); + const response = ctx.getResponse(); + const message = exception.message.replace(/\n/g, ''); + + switch (exception.code) { + case 'P2002': { + const status = HttpStatus.CONFLICT; + response.status(status).json({ + statusCode: status, + message: message, + }); + break; + } + case 'P2025': { + const status = HttpStatus.NOT_FOUND; + response.status(status).json({ + statusCode: status, + message: message, + }); + break; + } + default: + // default 500 error code + super.catch(exception, host); + break; + } + } +} \ No newline at end of file