next-crud
next-crud copied to clipboard
Handle invalid request
Context
From the example app, username is required.
API returns a 500 when trying to create a user without username.
curl 'https://qj3gn.sse.codesandbox.io/api/users' \
-H 'authority: qj3gn.sse.codesandbox.io' \
-H 'sec-ch-ua: "Google Chrome";v="93", " Not;A Brand";v="99", "Chromium";v="93"' \
-H 'sec-ch-ua-mobile: ?0' \
-H 'user-agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36' \
-H 'sec-ch-ua-platform: "Linux"' \
-H 'content-type: application/json' \
-H 'accept: */*' \
-H 'origin: https://qj3gn.sse.codesandbox.io' \
-H 'sec-fetch-site: same-origin' \
-H 'sec-fetch-mode: cors' \
-H 'sec-fetch-dest: empty' \
-H 'referer: https://qj3gn.sse.codesandbox.io/users/create' \
-H 'accept-language: en-US,en;q=0.9,fr;q=0.8' \
--data-raw '{}' \
--compressed
Error
Invalid `prisma.user.create()` invocation:
{
data: {
+ username: String,
? isAdmin?: Boolean | null,
? posts?: {
? create?: PostCreateWithoutUserInput | PostCreateWithoutUserInput,
? connect?: PostWhereUniqueInput | PostWhereUniqueInput,
? connectOrCreate?: PostCreateOrConnectWithoutuserInput | PostCreateOrConnectWithoutuserInput
? }
},
select: undefined,
include: undefined
}
Argument username for data.username is missing.
Expected
API should return a 400 instead of 500, with proper error handling like
{
errors: {
username: {
required: "username field is required"
}
}
}
I am having a similar issue, but a bigger issue here is that there is no way to allow the user to define their own error formatting.
The most obvious solution I found was to override handleError
in the adapter and throw your own HttpError
s, but this is still limited to returning plain text with the HTTP status text forcibly prepended.
The best I could do was to define my own error type (for example, say: new HttpErrorWithBody(400, { error: { path: 'email', type: 'not_unique' } })
), then catch that in my own onError
handler and use it to return the statusCode and body on the error object. The problem with this is that onError
isn't intended to be used this way, as right afterwards it proceeds to send the response body and status anyway—there's no way to disable this. One solution here would be to check res.headersSent
after onError
, but it just feels like a workaround to me.
There should probably be some way to define a function which is explicitly intended to format an error response. Perhaps something like this? (here I'm just replicating exactly the handling that is default today)
const handler = NextCrud({
adapter: new PrismaAdapter({
prismaClient: myPrismaClientInstance,
}),
sendErrorResponse: (req, res, error) => {
if (e instanceof HttpError) {
res.status(e.statusCode).send(e.message)
} else {
res.status(500).send(e.message)
}
}
})