#1 error handling improved

Signed-off-by: Benny Samir Hierl <bennysamir@posteo.de>
This commit is contained in:
Benny Samir Hierl 2022-02-06 11:23:47 +01:00
parent 9534bc270f
commit 14cded061f
5 changed files with 64 additions and 45 deletions

View file

@ -1,3 +1,40 @@
import { FastifyRequest, FastifyReply, FastifyError } from 'fastify'
import { Prisma } from '@prisma/client'
const errorIs = (e: unknown, c: string) =>
e instanceof Prisma.PrismaClientKnownRequestError && e.code === c
export const defaultErrorHandler = (
error: FastifyError,
request: FastifyRequest,
reply: FastifyReply
) => {
if (error.validation) {
error.code = '400'
reply.send(error)
} else if (errorIs(error, 'P2002')) {
reply.send(
uniqueKeyError(
// @ts-expect-error: Object is possibly 'undefined'
`${error.meta.target[0] || 'One of the fields'} has to be unique`
)
)
} else if (errorIs(error, 'P2025')) {
reply.callNotFound()
} else {
request.log.error(error)
const e = new httpError('unexpected error', 500, '500')
reply.send(e)
}
}
export const notFoundHandler = (
request: FastifyRequest,
reply: FastifyReply
) => {
reply.send(notFoundError())
}
class httpError extends Error {
code: string
statusCode: number
@ -10,10 +47,10 @@ class httpError extends Error {
}
}
export const notFoundError = () => {
const notFoundError = () => {
return new httpError('Not Found', 404, '404')
}
export const uniqueKeyError = (msg: string, code = '4001') => {
const uniqueKeyError = (msg: string, code = '4001') => {
return new httpError(msg, 422, code)
}

View file

@ -1,14 +1,13 @@
import { FastifyInstance } from 'fastify'
import { default as wishlistRoute } from './wishlist/'
import { notFoundError } from '../config/errors'
import { defaultErrorHandler, notFoundHandler } from '../config/errors'
export default {
register: (app: FastifyInstance) => {
return app.register(
async (app) => {
app.setNotFoundHandler((request, reply) => {
reply.send(notFoundError())
})
await app.setNotFoundHandler(notFoundHandler)
await app.setErrorHandler(defaultErrorHandler)
await app.register(wishlistRoute, { prefix: '/wishlist' })
},
{ prefix: '/api' }

View file

@ -1,8 +1,6 @@
import { Wishlist, WishlistItem } from '@/types'
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
import { wishlist } from '../../models'
import { prisma } from '../../services'
import { uniqueKeyError } from '../../config/errors'
import {
wishlistItemRequestSchema,
wishlistItemResponseSchema,
@ -25,13 +23,6 @@ export const createList = <RouteOptions>{
201: wishlistResponseSchema,
},
},
errorHandler: (error, request, reply) => {
if (error instanceof prisma.errorType && error.code === 'P2002') {
return reply.send(uniqueKeyError('Slugtext has to be unique'))
}
request.log.error(error)
reply.send(new Error('Unexptected Error'))
},
handler: async (request: FastifyRequest, reply: FastifyReply) => {
request.log.debug(request.body)
const item = await wishlist.create(request.body as Wishlist)
@ -44,17 +35,16 @@ export const createItem = <RouteOptions>{
url: '/:wishlistId/item',
schema: {
body: wishlistItemRequestSchema,
params: {
type: 'object',
properties: {
wishlistId: { type: 'string' },
},
},
response: {
201: wishlistItemResponseSchema,
},
},
errorHandler: (error, request, reply) => {
if (error instanceof prisma.errorType && error.code === 'P2025') {
return reply.callNotFound()
}
request.log.error(error)
reply.send(new Error('Unexptected Error'))
},
handler: async (request: createItemRequest, reply: FastifyReply) => {
request.log.debug(request.body)
const item = await wishlist.createItem(

View file

@ -1,5 +1,3 @@
import { uniqueKeyError } from '../../config/errors'
import { prisma } from '../../services'
import { Wishlist } from '@/types'
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
import { wishlist } from '../../models'
@ -28,20 +26,16 @@ export const updateList = <RouteOptions>{
url: '/:wishlistId',
schema: {
body: wishlistRequestSchema,
params: {
type: 'object',
properties: {
wishlistId: { type: 'string' },
},
},
response: {
200: wishlistResponseSchema,
},
},
errorHandler: (error, request, reply) => {
if (error instanceof prisma.errorType && error.code === 'P2002') {
return reply.send(uniqueKeyError('Slugtext has to be unique'))
}
if (error instanceof prisma.errorType && error.code === 'P2025') {
return reply.callNotFound()
}
request.log.error(error)
reply.send(new Error('Unexptected Error'))
},
handler: async (request: updateRequest, reply: FastifyReply) => {
request.log.debug(request.body)
const item = await wishlist.update(
@ -57,20 +51,21 @@ export const updateItem = <RouteOptions>{
url: '/:wishlistId/item/:itemId',
schema: {
body: wishlistItemRequestSchema,
params: {
type: 'object',
properties: {
wishlistId: { type: 'string' },
itemId: { type: 'number' },
},
},
response: {
200: wishlistItemResponseSchema,
},
},
handler: async (request: updateItemRequest, reply: FastifyReply) => {
request.log.debug(request.body)
const item = await wishlist.updateItem(
Number(request.params.itemId),
request.body
reply.send(
await wishlist.updateItem(Number(request.params.itemId), request.body)
)
if (item) {
reply.send(item)
} else {
reply.callNotFound()
}
},
}

View file

@ -1,9 +1,7 @@
import { PrismaClient, Prisma } from '@prisma/client'
import { PrismaClient } from '@prisma/client'
const client = new PrismaClient()
const errorType = Prisma.PrismaClientKnownRequestError
export default {
client,
errorType,
}