This repository was archived by the owner on Sep 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathhandleApiEndpointError.ts
68 lines (57 loc) · 1.71 KB
/
handleApiEndpointError.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
import { ApiError } from '@api/libs/ApiError'
import { SilentError } from '@common/libs/SilentError'
import { handleError } from './handleError'
import type { NextApiResponse } from 'next'
/**
* Handle internal API Endpoint errors and return an 4XX or 5XX response.
*
* @description
* If <isLast> is not set to `true`, the handler will rethrow a SilentError
* after sending the response to avoid any subsequent code to be run.
*/
export function handleApiEndpointError(
error: unknown,
path: string,
res: NextApiResponse,
isLast: boolean = false,
): never {
if (isLast && error instanceof SilentError) {
return undefined as never
}
const { message } = handleError(error, path)
const isProduction = process.env.NODE_ENV === 'production'
// Unhandled errors are a serious security issue if exposed
if (isProduction) {
// If `error.isExposed` is `true`, this handled error can be useful to the client,
// so let's expose its message but not its path
if (error instanceof ApiError && error.isExposed) {
const code = error.status
res.status(code).json({
code,
hasError: true,
message,
})
throw new SilentError()
}
// Otherwise, let's keep it generic
const code = 400
res.status(code).json({
code,
hasError: true,
message: 'Something went wrong. Please check your server logs.',
})
throw new SilentError()
}
// And in non-production environments, we can reveal (almost) everything
const code = error instanceof ApiError ? error.status : 400
res.status(code).json({
code,
hasError: true,
message,
path,
})
if (!isLast) {
throw new SilentError()
}
return undefined as never
}