Browse Source

Part 3: Building a REST API with NestJS and Prisma: Error Handling

master
Hendra Lin 3 years ago
parent
commit
72bd87d556
  1. 10
      src/articles/articles.controller.ts
  2. 6
      src/main.ts
  3. 7
      src/prisma-client-exception/prisma-client-exception.filter.spec.ts
  4. 39
      src/prisma-client-exception/prisma-client-exception.filter.ts

10
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 { ArticlesService } from './articles.service';
import { CreateArticleDto } from './dto/create-article.dto'; import { CreateArticleDto } from './dto/create-article.dto';
import { UpdateArticleDto } from './dto/update-article.dto'; import { UpdateArticleDto } from './dto/update-article.dto';
@ -30,8 +30,12 @@ export class ArticlesController {
@Get(':id') @Get(':id')
@ApiOkResponse({ type: ArticleEntity }) @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') @Patch(':id')

6
src/main.ts

@ -1,7 +1,8 @@
import { NestFactory } from '@nestjs/core';
import { HttpAdapterHost, NestFactory } from '@nestjs/core';
import { AppModule } from './app.module'; import { AppModule } from './app.module';
import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger'; import { SwaggerModule, DocumentBuilder } from '@nestjs/swagger';
import { ValidationPipe } from '@nestjs/common' import { ValidationPipe } from '@nestjs/common'
import { PrismaClientExceptionFilter } from './prisma-client-exception/prisma-client-exception.filter';
async function bootstrap() { async function bootstrap() {
const app = await NestFactory.create(AppModule); const app = await NestFactory.create(AppModule);
@ -17,6 +18,9 @@ async function bootstrap() {
const document = SwaggerModule.createDocument(app, config) const document = SwaggerModule.createDocument(app, config)
SwaggerModule.setup('api', app, document) SwaggerModule.setup('api', app, document)
const { httpAdapter } = app.get(HttpAdapterHost)
app.useGlobalFilters(new PrismaClientExceptionFilter(httpAdapter))
await app.listen(3000); await app.listen(3000);
} }
bootstrap(); bootstrap();

7
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();
});
});

39
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<Response>();
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;
}
}
}
Loading…
Cancel
Save