mirror of
https://github.com/ThisIsBenny/wishlist-app.git
synced 2025-06-07 05:57:41 +00:00
#1 error handling improved
Signed-off-by: Benny Samir Hierl <bennysamir@posteo.de>
This commit is contained in:
parent
9534bc270f
commit
14cded061f
5 changed files with 64 additions and 45 deletions
|
@ -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 {
|
class httpError extends Error {
|
||||||
code: string
|
code: string
|
||||||
statusCode: number
|
statusCode: number
|
||||||
|
@ -10,10 +47,10 @@ class httpError extends Error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const notFoundError = () => {
|
const notFoundError = () => {
|
||||||
return new httpError('Not Found', 404, '404')
|
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)
|
return new httpError(msg, 422, code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
import { FastifyInstance } from 'fastify'
|
import { FastifyInstance } from 'fastify'
|
||||||
import { default as wishlistRoute } from './wishlist/'
|
import { default as wishlistRoute } from './wishlist/'
|
||||||
import { notFoundError } from '../config/errors'
|
import { defaultErrorHandler, notFoundHandler } from '../config/errors'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
register: (app: FastifyInstance) => {
|
register: (app: FastifyInstance) => {
|
||||||
return app.register(
|
return app.register(
|
||||||
async (app) => {
|
async (app) => {
|
||||||
app.setNotFoundHandler((request, reply) => {
|
await app.setNotFoundHandler(notFoundHandler)
|
||||||
reply.send(notFoundError())
|
await app.setErrorHandler(defaultErrorHandler)
|
||||||
})
|
|
||||||
await app.register(wishlistRoute, { prefix: '/wishlist' })
|
await app.register(wishlistRoute, { prefix: '/wishlist' })
|
||||||
},
|
},
|
||||||
{ prefix: '/api' }
|
{ prefix: '/api' }
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
import { Wishlist, WishlistItem } from '@/types'
|
import { Wishlist, WishlistItem } from '@/types'
|
||||||
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
|
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
|
||||||
import { wishlist } from '../../models'
|
import { wishlist } from '../../models'
|
||||||
import { prisma } from '../../services'
|
|
||||||
import { uniqueKeyError } from '../../config/errors'
|
|
||||||
import {
|
import {
|
||||||
wishlistItemRequestSchema,
|
wishlistItemRequestSchema,
|
||||||
wishlistItemResponseSchema,
|
wishlistItemResponseSchema,
|
||||||
|
@ -25,13 +23,6 @@ export const createList = <RouteOptions>{
|
||||||
201: wishlistResponseSchema,
|
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) => {
|
handler: async (request: FastifyRequest, reply: FastifyReply) => {
|
||||||
request.log.debug(request.body)
|
request.log.debug(request.body)
|
||||||
const item = await wishlist.create(request.body as Wishlist)
|
const item = await wishlist.create(request.body as Wishlist)
|
||||||
|
@ -44,17 +35,16 @@ export const createItem = <RouteOptions>{
|
||||||
url: '/:wishlistId/item',
|
url: '/:wishlistId/item',
|
||||||
schema: {
|
schema: {
|
||||||
body: wishlistItemRequestSchema,
|
body: wishlistItemRequestSchema,
|
||||||
|
params: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
wishlistId: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
response: {
|
response: {
|
||||||
201: wishlistItemResponseSchema,
|
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) => {
|
handler: async (request: createItemRequest, reply: FastifyReply) => {
|
||||||
request.log.debug(request.body)
|
request.log.debug(request.body)
|
||||||
const item = await wishlist.createItem(
|
const item = await wishlist.createItem(
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
import { uniqueKeyError } from '../../config/errors'
|
|
||||||
import { prisma } from '../../services'
|
|
||||||
import { Wishlist } from '@/types'
|
import { Wishlist } from '@/types'
|
||||||
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
|
import { FastifyRequest, FastifyReply, RouteOptions } from 'fastify'
|
||||||
import { wishlist } from '../../models'
|
import { wishlist } from '../../models'
|
||||||
|
@ -28,20 +26,16 @@ export const updateList = <RouteOptions>{
|
||||||
url: '/:wishlistId',
|
url: '/:wishlistId',
|
||||||
schema: {
|
schema: {
|
||||||
body: wishlistRequestSchema,
|
body: wishlistRequestSchema,
|
||||||
|
params: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
wishlistId: { type: 'string' },
|
||||||
|
},
|
||||||
|
},
|
||||||
response: {
|
response: {
|
||||||
200: wishlistResponseSchema,
|
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) => {
|
handler: async (request: updateRequest, reply: FastifyReply) => {
|
||||||
request.log.debug(request.body)
|
request.log.debug(request.body)
|
||||||
const item = await wishlist.update(
|
const item = await wishlist.update(
|
||||||
|
@ -57,20 +51,21 @@ export const updateItem = <RouteOptions>{
|
||||||
url: '/:wishlistId/item/:itemId',
|
url: '/:wishlistId/item/:itemId',
|
||||||
schema: {
|
schema: {
|
||||||
body: wishlistItemRequestSchema,
|
body: wishlistItemRequestSchema,
|
||||||
|
params: {
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
wishlistId: { type: 'string' },
|
||||||
|
itemId: { type: 'number' },
|
||||||
|
},
|
||||||
|
},
|
||||||
response: {
|
response: {
|
||||||
200: wishlistItemResponseSchema,
|
200: wishlistItemResponseSchema,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
handler: async (request: updateItemRequest, reply: FastifyReply) => {
|
handler: async (request: updateItemRequest, reply: FastifyReply) => {
|
||||||
request.log.debug(request.body)
|
request.log.debug(request.body)
|
||||||
const item = await wishlist.updateItem(
|
reply.send(
|
||||||
Number(request.params.itemId),
|
await wishlist.updateItem(Number(request.params.itemId), request.body)
|
||||||
request.body
|
|
||||||
)
|
)
|
||||||
if (item) {
|
|
||||||
reply.send(item)
|
|
||||||
} else {
|
|
||||||
reply.callNotFound()
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
import { PrismaClient, Prisma } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|
||||||
const client = new PrismaClient()
|
const client = new PrismaClient()
|
||||||
const errorType = Prisma.PrismaClientKnownRequestError
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
client,
|
client,
|
||||||
errorType,
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue