@emoyly/problem 5.0.7 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.editorconfig +11 -0
- package/.vscode/extensions.json +7 -0
- package/.vscode/settings.json +2 -0
- package/.yarn/versions/524dd037.yml +0 -0
- package/.yarn/versions/b57d536b.yml +0 -0
- package/.yarn/versions/d984e272.yml +0 -0
- package/cjs/defaults/index.d.ts +7 -0
- package/cjs/defaults/index.js +17 -0
- package/cjs/index.d.ts +5 -0
- package/cjs/index.js +24 -0
- package/{middleware → cjs/middleware}/axios.d.ts +2 -2
- package/cjs/middleware/axios.js +24 -0
- package/{middleware → cjs/middleware}/base.d.ts +3 -3
- package/cjs/middleware/base.js +52 -0
- package/{middleware → cjs/middleware}/express.d.ts +2 -2
- package/cjs/middleware/express.js +65 -0
- package/cjs/package.json +3 -0
- package/cjs/parsers/axios.d.ts +3 -0
- package/cjs/parsers/axios.js +55 -0
- package/cjs/parsers/jsonwebtoken.d.ts +3 -0
- package/{parsers → cjs/parsers}/jsonwebtoken.js +4 -4
- package/cjs/parsers/mikroorm.d.ts +3 -0
- package/{parsers → cjs/parsers}/mikroorm.js +7 -3
- package/cjs/parsers/tsoa.d.ts +3 -0
- package/{parsers → cjs/parsers}/tsoa.js +10 -4
- package/{problem.d.ts → cjs/problem.d.ts} +1 -1
- package/{problem.js → cjs/problem.js} +24 -23
- package/cjs/tsconfig.tsbuildinfo +1 -0
- package/{typings → cjs/typings}/codes.d.ts +1 -1
- package/{typings → cjs/typings}/events.d.ts +1 -1
- package/cjs/typings/index.d.ts +5 -0
- package/{typings → cjs/typings}/index.js +5 -5
- package/{typings → cjs/typings}/middleware.d.ts +1 -1
- package/{typings → cjs/typings}/parser.d.ts +1 -1
- package/{util → cjs/util}/events.d.ts +2 -2
- package/cjs/util/events.js +27 -0
- package/{util → cjs/util}/getProblems.d.ts +2 -2
- package/{util → cjs/util}/getProblems.js +10 -11
- package/{util → cjs/util}/isProblemArray.d.ts +1 -1
- package/{util → cjs/util}/isProblemArray.js +3 -4
- package/{util → cjs/util}/misc.d.ts +1 -1
- package/cjs/util/misc.js +19 -0
- package/{util → cjs/util}/version.d.ts +1 -1
- package/{util → cjs/util}/version.js +3 -3
- package/eslint.config.mjs +5 -0
- package/esm/defaults/4xx.d.ts +147 -0
- package/esm/defaults/4xx.js +148 -0
- package/esm/defaults/5xx.d.ts +57 -0
- package/esm/defaults/5xx.js +58 -0
- package/esm/defaults/aws.d.ts +12 -0
- package/esm/defaults/aws.js +13 -0
- package/esm/defaults/cloudflare.d.ts +47 -0
- package/esm/defaults/cloudflare.js +49 -0
- package/esm/defaults/iis.d.ts +17 -0
- package/esm/defaults/iis.js +18 -0
- package/esm/defaults/index.d.ts +7 -0
- package/esm/defaults/index.js +7 -0
- package/esm/defaults/nginx.d.ts +32 -0
- package/esm/defaults/nginx.js +33 -0
- package/esm/defaults/others.d.ts +37 -0
- package/esm/defaults/others.js +37 -0
- package/esm/index.d.ts +5 -0
- package/esm/index.js +5 -0
- package/esm/middleware/axios.d.ts +13 -0
- package/esm/middleware/axios.js +20 -0
- package/esm/middleware/base.d.ts +24 -0
- package/esm/middleware/base.js +48 -0
- package/esm/middleware/express.d.ts +19 -0
- package/esm/middleware/express.js +61 -0
- package/esm/package.json +3 -0
- package/esm/parsers/axios.d.ts +3 -0
- package/esm/parsers/axios.js +53 -0
- package/esm/parsers/jsonwebtoken.d.ts +3 -0
- package/esm/parsers/jsonwebtoken.js +94 -0
- package/esm/parsers/mikroorm.d.ts +3 -0
- package/esm/parsers/mikroorm.js +17 -0
- package/esm/parsers/tsoa.d.ts +3 -0
- package/esm/parsers/tsoa.js +21 -0
- package/esm/problem.d.ts +14 -0
- package/esm/problem.js +56 -0
- package/esm/tsconfig.tsbuildinfo +1 -0
- package/esm/typings/codes.d.ts +5 -0
- package/esm/typings/codes.js +1 -0
- package/esm/typings/events.d.ts +2 -0
- package/esm/typings/events.js +1 -0
- package/esm/typings/index.d.ts +5 -0
- package/esm/typings/index.js +5 -0
- package/esm/typings/middleware.d.ts +9 -0
- package/esm/typings/middleware.js +1 -0
- package/esm/typings/parser.d.ts +2 -0
- package/esm/typings/parser.js +1 -0
- package/esm/typings/problem.d.ts +24 -0
- package/esm/typings/problem.js +11 -0
- package/esm/util/defaults.d.ts +4 -0
- package/esm/util/defaults.js +4 -0
- package/esm/util/events.d.ts +16 -0
- package/esm/util/events.js +25 -0
- package/esm/util/getProblems.d.ts +5 -0
- package/esm/util/getProblems.js +40 -0
- package/esm/util/isProblemArray.d.ts +2 -0
- package/esm/util/isProblemArray.js +6 -0
- package/esm/util/misc.d.ts +2 -0
- package/esm/util/misc.js +16 -0
- package/esm/util/version.d.ts +3 -0
- package/esm/util/version.js +16 -0
- package/package.json +51 -28
- package/scripts/ensureCorrectVersion.js +8 -4
- package/src/defaults/4xx.ts +149 -0
- package/src/defaults/5xx.ts +59 -0
- package/src/defaults/aws.ts +14 -0
- package/src/defaults/cloudflare.ts +50 -0
- package/src/defaults/iis.ts +19 -0
- package/src/defaults/index.ts +7 -0
- package/src/defaults/nginx.ts +34 -0
- package/src/defaults/others.ts +37 -0
- package/src/index.ts +5 -0
- package/src/middleware/axios.ts +29 -0
- package/src/middleware/base.ts +64 -0
- package/src/middleware/express.ts +72 -0
- package/src/parsers/axios.ts +61 -0
- package/src/parsers/jsonwebtoken.ts +104 -0
- package/src/parsers/mikroorm.ts +21 -0
- package/src/parsers/tsoa.ts +25 -0
- package/src/problem.ts +56 -0
- package/src/typings/codes.ts +6 -0
- package/src/typings/events.ts +3 -0
- package/src/typings/index.ts +5 -0
- package/src/typings/middleware.ts +11 -0
- package/src/typings/parser.ts +3 -0
- package/src/typings/problem.ts +27 -0
- package/src/util/defaults.ts +4 -0
- package/src/util/events.ts +34 -0
- package/src/util/getProblems.ts +43 -0
- package/src/util/isProblemArray.ts +6 -0
- package/src/util/misc.ts +20 -0
- package/src/util/version.ts +16 -0
- package/tsconfig.json +15 -0
- package/defaults/index.d.ts +0 -7
- package/defaults/index.js +0 -17
- package/index.d.ts +0 -5
- package/index.js +0 -39
- package/middleware/axios.js +0 -36
- package/middleware/base.js +0 -56
- package/middleware/express.js +0 -60
- package/parsers/axios.d.ts +0 -3
- package/parsers/axios.js +0 -41
- package/parsers/jsonwebtoken.d.ts +0 -3
- package/parsers/mikroorm.d.ts +0 -3
- package/parsers/tsoa.d.ts +0 -3
- package/tsconfig.tsbuildinfo +0 -1
- package/typings/index.d.ts +0 -5
- package/util/events.js +0 -29
- package/util/misc.js +0 -43
- /package/{defaults → cjs/defaults}/4xx.d.ts +0 -0
- /package/{defaults → cjs/defaults}/4xx.js +0 -0
- /package/{defaults → cjs/defaults}/5xx.d.ts +0 -0
- /package/{defaults → cjs/defaults}/5xx.js +0 -0
- /package/{defaults → cjs/defaults}/aws.d.ts +0 -0
- /package/{defaults → cjs/defaults}/aws.js +0 -0
- /package/{defaults → cjs/defaults}/cloudflare.d.ts +0 -0
- /package/{defaults → cjs/defaults}/cloudflare.js +0 -0
- /package/{defaults → cjs/defaults}/iis.d.ts +0 -0
- /package/{defaults → cjs/defaults}/iis.js +0 -0
- /package/{defaults → cjs/defaults}/nginx.d.ts +0 -0
- /package/{defaults → cjs/defaults}/nginx.js +0 -0
- /package/{defaults → cjs/defaults}/others.d.ts +0 -0
- /package/{defaults → cjs/defaults}/others.js +0 -0
- /package/{typings → cjs/typings}/codes.js +0 -0
- /package/{typings → cjs/typings}/events.js +0 -0
- /package/{typings → cjs/typings}/middleware.js +0 -0
- /package/{typings → cjs/typings}/parser.js +0 -0
- /package/{typings → cjs/typings}/problem.d.ts +0 -0
- /package/{typings → cjs/typings}/problem.js +0 -0
- /package/{util → cjs/util}/defaults.d.ts +0 -0
- /package/{util → cjs/util}/defaults.js +0 -0
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
// Source: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
400: {
|
|
5
|
+
status: 400,
|
|
6
|
+
title: 'Bad Request',
|
|
7
|
+
type: '/errors/defaults/4xx/badrequest',
|
|
8
|
+
},
|
|
9
|
+
401: {
|
|
10
|
+
status: 401,
|
|
11
|
+
title: 'Unauthorized',
|
|
12
|
+
type: '/errors/defaults/4xx/unauthorized',
|
|
13
|
+
},
|
|
14
|
+
402: {
|
|
15
|
+
status: 402,
|
|
16
|
+
title: 'Payment Required',
|
|
17
|
+
type: '/errors/defaults/4xx/paymentrequired',
|
|
18
|
+
},
|
|
19
|
+
403: {
|
|
20
|
+
status: 403,
|
|
21
|
+
title: 'Forbidden',
|
|
22
|
+
type: '/errors/defaults/4xx/forbidden',
|
|
23
|
+
},
|
|
24
|
+
404: {
|
|
25
|
+
status: 404,
|
|
26
|
+
title: 'Not Found',
|
|
27
|
+
type: '/errors/defaults/4xx/notfound',
|
|
28
|
+
},
|
|
29
|
+
406: {
|
|
30
|
+
status: 406,
|
|
31
|
+
title: 'Not Acceptable',
|
|
32
|
+
type: 'errors/defaults/4xx/notacceptable'
|
|
33
|
+
},
|
|
34
|
+
405: {
|
|
35
|
+
status: 405,
|
|
36
|
+
title: 'Method Not Allowed',
|
|
37
|
+
type: 'errors/defaults/4xx/methodnotallowed'
|
|
38
|
+
},
|
|
39
|
+
407: {
|
|
40
|
+
status: 407,
|
|
41
|
+
title: 'Proxy Authentication Required (RFC 7235)',
|
|
42
|
+
type: 'errors/defaults/4xx/proxyauthenticationrequired'
|
|
43
|
+
},
|
|
44
|
+
408: {
|
|
45
|
+
status: 408,
|
|
46
|
+
title: 'Request Timeout',
|
|
47
|
+
type: 'errors/defaults/4xx/requesttimeout'
|
|
48
|
+
},
|
|
49
|
+
409: {
|
|
50
|
+
status: 409,
|
|
51
|
+
title: 'Conflict',
|
|
52
|
+
type: 'errors/defaults/4xx/conflict'
|
|
53
|
+
},
|
|
54
|
+
410: {
|
|
55
|
+
status: 410,
|
|
56
|
+
title: 'Gone',
|
|
57
|
+
type: 'errors/defaults/4xx/gone'
|
|
58
|
+
},
|
|
59
|
+
411: {
|
|
60
|
+
status: 411,
|
|
61
|
+
title: 'Length Required',
|
|
62
|
+
type: 'errors/defaults/4xx/lengthrequired'
|
|
63
|
+
},
|
|
64
|
+
412: {
|
|
65
|
+
status: 412,
|
|
66
|
+
title: 'Precondition Failed (RFC 7232)',
|
|
67
|
+
type: 'errors/defaults/4xx/preconditionfailed'
|
|
68
|
+
},
|
|
69
|
+
413: {
|
|
70
|
+
status: 413,
|
|
71
|
+
title: 'Payload Too Large (RFC 7231)',
|
|
72
|
+
type: 'errors/defaults/4xx/payloadtoolarge'
|
|
73
|
+
},
|
|
74
|
+
414: {
|
|
75
|
+
status: 414,
|
|
76
|
+
title: 'URI Too Long (RFC 7231)',
|
|
77
|
+
type: 'errors/defaults/4xx/uritoolong'
|
|
78
|
+
},
|
|
79
|
+
415: {
|
|
80
|
+
status: 415,
|
|
81
|
+
title: 'Unsupported Media Type (RFC 7231)',
|
|
82
|
+
type: 'errors/defaults/4xx/unsupportedmediatype'
|
|
83
|
+
},
|
|
84
|
+
416: {
|
|
85
|
+
status: 416,
|
|
86
|
+
title: 'Range Not Satisfiable (RFC 7233)',
|
|
87
|
+
type: 'errors/defaults/4xx/rangenotsatisfiable'
|
|
88
|
+
},
|
|
89
|
+
417: {
|
|
90
|
+
status: 417,
|
|
91
|
+
title: 'Expectation Failed',
|
|
92
|
+
type: 'errors/defaults/4xx/expectationfailed'
|
|
93
|
+
},
|
|
94
|
+
418: {
|
|
95
|
+
status: 418,
|
|
96
|
+
title: 'I\'m a teapot (RFC 2324, RFC 7168)',
|
|
97
|
+
type: 'errors/defaults/4xx/i\'mateapot'
|
|
98
|
+
},
|
|
99
|
+
421: {
|
|
100
|
+
status: 421,
|
|
101
|
+
title: 'Misdirected Request (RFC 7540)',
|
|
102
|
+
type: 'errors/defaults/4xx/misdirectedrequest'
|
|
103
|
+
},
|
|
104
|
+
422: {
|
|
105
|
+
status: 422,
|
|
106
|
+
title: 'Unprocessable Entity (WebDAV; RFC 4918)',
|
|
107
|
+
type: 'errors/defaults/4xx/unprocessableentity'
|
|
108
|
+
},
|
|
109
|
+
423: {
|
|
110
|
+
status: 423,
|
|
111
|
+
title: 'Locked (WebDAV; RFC 4918)',
|
|
112
|
+
type: 'errors/defaults/4xx/locked'
|
|
113
|
+
},
|
|
114
|
+
424: {
|
|
115
|
+
status: 424,
|
|
116
|
+
title: 'Failed Dependency (WebDAV; RFC 4918)',
|
|
117
|
+
type: 'errors/defaults/4xx/faileddependency'
|
|
118
|
+
},
|
|
119
|
+
425: {
|
|
120
|
+
status: 425,
|
|
121
|
+
title: 'Too Early (RFC 8470)',
|
|
122
|
+
type: 'errors/defaults/4xx/tooearly'
|
|
123
|
+
},
|
|
124
|
+
426: {
|
|
125
|
+
status: 426,
|
|
126
|
+
title: 'Upgrade Required',
|
|
127
|
+
type: 'errors/defaults/4xx/upgraderequired'
|
|
128
|
+
},
|
|
129
|
+
428: {
|
|
130
|
+
status: 428,
|
|
131
|
+
title: 'Precondition Required (RFC 6585)',
|
|
132
|
+
type: 'errors/defaults/4xx/preconditionrequired'
|
|
133
|
+
},
|
|
134
|
+
429: {
|
|
135
|
+
status: 429,
|
|
136
|
+
title: 'Too Many Requests (RFC 6585)',
|
|
137
|
+
type: 'errors/defaults/4xx/toomanyrequests'
|
|
138
|
+
},
|
|
139
|
+
431: {
|
|
140
|
+
status: 431,
|
|
141
|
+
title: 'Request Header Fields Too Large (RFC 6585)',
|
|
142
|
+
type: 'errors/defaults/4xx/requestheaderfieldstoolarge'
|
|
143
|
+
},
|
|
144
|
+
451: {
|
|
145
|
+
status: 451,
|
|
146
|
+
title: 'Unavailable For Legal Reasons (RFC 7725)',
|
|
147
|
+
type: 'errors/defaults/4xx/unavailableforlegalreasons'
|
|
148
|
+
}
|
|
149
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
// Source: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
500: {
|
|
5
|
+
status: 500,
|
|
6
|
+
title: 'Internal Server Error',
|
|
7
|
+
type: 'errors/defaults/5xx/internalservererror'
|
|
8
|
+
},
|
|
9
|
+
501: {
|
|
10
|
+
status: 501,
|
|
11
|
+
title: 'Not Implemented',
|
|
12
|
+
type: 'errors/defaults/5xx/notimplemented'
|
|
13
|
+
},
|
|
14
|
+
502: {
|
|
15
|
+
status: 502,
|
|
16
|
+
title: 'Bad Gateway',
|
|
17
|
+
type: 'errors/defaults/5xx/badgateway'
|
|
18
|
+
},
|
|
19
|
+
503: {
|
|
20
|
+
status: 503,
|
|
21
|
+
title: 'Service Unavailable',
|
|
22
|
+
type: 'errors/defaults/5xx/serviceunavailable'
|
|
23
|
+
},
|
|
24
|
+
504: {
|
|
25
|
+
status: 504,
|
|
26
|
+
title: 'Gateway Timeout',
|
|
27
|
+
type: 'errors/defaults/5xx/gatewaytimeout'
|
|
28
|
+
},
|
|
29
|
+
505: {
|
|
30
|
+
status: 505,
|
|
31
|
+
title: 'HTTP Version Not Supported',
|
|
32
|
+
type: 'errors/defaults/5xx/httpversionnotsupported'
|
|
33
|
+
},
|
|
34
|
+
506: {
|
|
35
|
+
status: 506,
|
|
36
|
+
title: 'Variant Also Negotiates (RFC 2295)',
|
|
37
|
+
type: 'errors/defaults/5xx/variantalsonegotiates'
|
|
38
|
+
},
|
|
39
|
+
507: {
|
|
40
|
+
status: 507,
|
|
41
|
+
title: 'Insufficient Storage (WebDAV; RFC 4918)',
|
|
42
|
+
type: 'errors/defaults/5xx/insufficientstorage'
|
|
43
|
+
},
|
|
44
|
+
508: {
|
|
45
|
+
status: 508,
|
|
46
|
+
title: 'Loop Detected (WebDAV; RFC 5842)',
|
|
47
|
+
type: 'errors/defaults/5xx/loopdetected'
|
|
48
|
+
},
|
|
49
|
+
511: {
|
|
50
|
+
status: 511,
|
|
51
|
+
title: 'Network Authentication Required (RFC 6585)',
|
|
52
|
+
type: 'errors/defaults/5xx/networkauthenticationrequired'
|
|
53
|
+
},
|
|
54
|
+
510: {
|
|
55
|
+
status: 510,
|
|
56
|
+
title: 'Not Extended (RFC 2774)',
|
|
57
|
+
type: 'errors/defaults/5xx/notextended'
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Source: https://docs.aws.amazon.com/elasticloadbalancing/latest/application/load-balancer-troubleshooting.html
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
460: {
|
|
5
|
+
status: 460,
|
|
6
|
+
title: 'Client closed connection before idle timeout period elapsed',
|
|
7
|
+
type: '/errors/defaults/aws/clientclosedbeforetimeout',
|
|
8
|
+
},
|
|
9
|
+
463: {
|
|
10
|
+
status: 463,
|
|
11
|
+
title: 'X-Forwarded-For contains more than 30 ips',
|
|
12
|
+
type: '/errors/defaults/aws/toomanyips'
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// Source: https://support.cloudflare.com/hc/en-us/articles/115003011431
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
520: {
|
|
5
|
+
status: 520,
|
|
6
|
+
title: 'Web Server returned an unknown error',
|
|
7
|
+
type: '/errors/defaults/cloudflare/unknownerror',
|
|
8
|
+
},
|
|
9
|
+
521: {
|
|
10
|
+
status: 521,
|
|
11
|
+
title: 'Web server is down',
|
|
12
|
+
type: '/errors/defaults/cloudflare/webserverdown',
|
|
13
|
+
},
|
|
14
|
+
522: {
|
|
15
|
+
status: 522,
|
|
16
|
+
title: 'Connection timed out',
|
|
17
|
+
type: '/errors/defaults/cloudflare/connectiontimeout',
|
|
18
|
+
},
|
|
19
|
+
523: {
|
|
20
|
+
status: 523,
|
|
21
|
+
title: 'Origin is unreachable',
|
|
22
|
+
type: '/errors/defaults/cloudflare/originunreachable'
|
|
23
|
+
},
|
|
24
|
+
524: {
|
|
25
|
+
status: 524,
|
|
26
|
+
title: 'A timeout occurred',
|
|
27
|
+
type: '/errors/defaults/cloudflare/timeout'
|
|
28
|
+
},
|
|
29
|
+
525: {
|
|
30
|
+
status: 525,
|
|
31
|
+
title: 'SSL handshake failed',
|
|
32
|
+
type: '/errors/defaults/cloudflare/sslhandshakefail'
|
|
33
|
+
},
|
|
34
|
+
526: {
|
|
35
|
+
status: 526,
|
|
36
|
+
title: 'Invalid SSL certificate',
|
|
37
|
+
type: '/errors/defaults/cloudflare/invalidssl'
|
|
38
|
+
},
|
|
39
|
+
// A 527 error indicates an interrupted connection between Cloudflare and your origin's Railgun server (rg-listener)
|
|
40
|
+
527: {
|
|
41
|
+
status: 527,
|
|
42
|
+
title: 'Railgun Listener to origin error',
|
|
43
|
+
type: '/errors/defaults/cloudflare/railgunoriginerr'
|
|
44
|
+
},
|
|
45
|
+
530: {
|
|
46
|
+
status: 530,
|
|
47
|
+
title: 'Cloudflare returned 1xxx error',
|
|
48
|
+
type: '/errors/defaults/cloudflare/1xxx'
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// Source: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
440: {
|
|
5
|
+
status: 440,
|
|
6
|
+
title: 'Login Time-out',
|
|
7
|
+
type: '/errors/defaults/iis/logintimeout',
|
|
8
|
+
},
|
|
9
|
+
449: {
|
|
10
|
+
status: 449,
|
|
11
|
+
title: 'Retry with required information',
|
|
12
|
+
type: '/errors/defaults/iis/retrywith'
|
|
13
|
+
},
|
|
14
|
+
451: {
|
|
15
|
+
status: 451,
|
|
16
|
+
title: 'Redirect',
|
|
17
|
+
type: '/errors/defaults/iis/redirect'
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { statusCodes as codes4xx } from '../defaults/4xx.js'
|
|
2
|
+
export { statusCodes as codes5xx } from '../defaults/5xx.js'
|
|
3
|
+
export { statusCodes as codesAws } from '../defaults/aws.js'
|
|
4
|
+
export { statusCodes as codesCloudflare } from '../defaults/cloudflare.js'
|
|
5
|
+
export { statusCodes as codesIis } from '../defaults/iis.js'
|
|
6
|
+
export { statusCodes as codesNginx } from '../defaults/nginx.js'
|
|
7
|
+
export { otherErrors } from '../defaults/others.js'
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// Source: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
|
2
|
+
|
|
3
|
+
export const statusCodes = {
|
|
4
|
+
444: {
|
|
5
|
+
status: 494,
|
|
6
|
+
title: 'No Response',
|
|
7
|
+
type: '/errors/defaults/nginx/noresponse',
|
|
8
|
+
},
|
|
9
|
+
494: {
|
|
10
|
+
status: 494,
|
|
11
|
+
title: 'Request header too large',
|
|
12
|
+
type: '/errors/defaults/nginx/headertoolarge',
|
|
13
|
+
},
|
|
14
|
+
495: {
|
|
15
|
+
status: 495,
|
|
16
|
+
title: 'SSL Certificate Error',
|
|
17
|
+
type: '/errors/defaults/nginx/sslcerterr'
|
|
18
|
+
},
|
|
19
|
+
496: {
|
|
20
|
+
status: 496,
|
|
21
|
+
title: 'SSL Certificate Required',
|
|
22
|
+
type: '/errors/defaults/nginx/sslcertrequired'
|
|
23
|
+
},
|
|
24
|
+
497: {
|
|
25
|
+
status: 497,
|
|
26
|
+
title: 'HTTP Request Sent to HTTPS Port',
|
|
27
|
+
type: '/errors/defaults/nginx/httpreqtohttpsport'
|
|
28
|
+
},
|
|
29
|
+
499: {
|
|
30
|
+
status: 499,
|
|
31
|
+
title: 'Client Closed Request',
|
|
32
|
+
type: '/errors/defaults/nginx/clientclosedreq'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export const otherErrors = {
|
|
2
|
+
'unknown': {
|
|
3
|
+
status: 500,
|
|
4
|
+
title: 'Unknown error',
|
|
5
|
+
type: '/errors/defaults/others/unknown',
|
|
6
|
+
},
|
|
7
|
+
'corsError': {
|
|
8
|
+
status: 401,
|
|
9
|
+
title: 'Request not allowed by CORS policy',
|
|
10
|
+
type: '/errors/defaults/others/corsdenied',
|
|
11
|
+
},
|
|
12
|
+
'problemParseError': {
|
|
13
|
+
status: 1000,
|
|
14
|
+
title: 'Could not parse problem details',
|
|
15
|
+
type: '/errors/defaults/others/problemparseerror',
|
|
16
|
+
},
|
|
17
|
+
'problemJsonError': {
|
|
18
|
+
status: 1000,
|
|
19
|
+
title: 'Could not parse problem JSON',
|
|
20
|
+
type: '/errors/defaults/others/problemjsonerror',
|
|
21
|
+
},
|
|
22
|
+
'notAnError': {
|
|
23
|
+
status: 1000,
|
|
24
|
+
title: 'Not an error',
|
|
25
|
+
type: '/errors/defaults/others/notanerror',
|
|
26
|
+
},
|
|
27
|
+
'networkError': {
|
|
28
|
+
status: 1000,
|
|
29
|
+
title: 'Network error',
|
|
30
|
+
type: '/errors/defaults/others/networkerror'
|
|
31
|
+
},
|
|
32
|
+
'inputValidationError': {
|
|
33
|
+
status: 400,
|
|
34
|
+
title: 'Input failed validation',
|
|
35
|
+
type: '/errors/defaults/others/validationerror'
|
|
36
|
+
}
|
|
37
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { PartialMiddlewareOptions } from '../typings/middleware.js'
|
|
2
|
+
import { MiddlewareBase } from './base.js'
|
|
3
|
+
import axiosParser from '../parsers/axios.js'
|
|
4
|
+
import events from '../util/events.js'
|
|
5
|
+
|
|
6
|
+
type InterceptorArray = [undefined, (error: unknown) => Promise<never>]
|
|
7
|
+
|
|
8
|
+
export class AxiosMiddleware extends MiddlewareBase {
|
|
9
|
+
name = 'axios'
|
|
10
|
+
|
|
11
|
+
constructor(options?: PartialMiddlewareOptions) {
|
|
12
|
+
super({
|
|
13
|
+
'parsers': [axiosParser]
|
|
14
|
+
}, options)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
interceptor = async (error: unknown) => {
|
|
18
|
+
const problems = await this.parse(error)
|
|
19
|
+
|
|
20
|
+
events.emit(problems)
|
|
21
|
+
|
|
22
|
+
return Promise.reject(problems)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @example instance.interceptors.response.use(...middleware.use())
|
|
27
|
+
*/
|
|
28
|
+
use = (): InterceptorArray => [undefined, this.interceptor]
|
|
29
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { otherErrors } from '../defaults/index.js'
|
|
2
|
+
import { Problem } from '../problem.js'
|
|
3
|
+
import type { ProblemOpts } from '../typings/index.js'
|
|
4
|
+
import type { MiddlewareOptions, PartialMiddlewareOptions } from '../typings/middleware.js'
|
|
5
|
+
import { getProblems } from '../util/getProblems.js'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Middleware collects errors from somewhere, transforms them into something recognizable by a parser, and then passes them to the parsers, and then returns an array of Problems to whatever is using the middleware
|
|
9
|
+
*/
|
|
10
|
+
export abstract class MiddlewareBase {
|
|
11
|
+
options: MiddlewareOptions
|
|
12
|
+
abstract name: string
|
|
13
|
+
/**
|
|
14
|
+
* When nothing is returned from the parsers, just throw in a default "fallback" Problem object, so that a Problem is still actually returned/emitted
|
|
15
|
+
*/
|
|
16
|
+
enableFallback = true
|
|
17
|
+
|
|
18
|
+
constructor(defaultOptions: MiddlewareOptions, options?: PartialMiddlewareOptions) {
|
|
19
|
+
this.options = { ...defaultOptions, ...options }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Call this function when you want to use the middleware function
|
|
24
|
+
*/
|
|
25
|
+
abstract use(): unknown
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Parse input using parsers
|
|
29
|
+
*/
|
|
30
|
+
parse = async (input: unknown): Promise<Problem[]> => {
|
|
31
|
+
const problems: Problem[] = []
|
|
32
|
+
|
|
33
|
+
const prob = getProblems(input)
|
|
34
|
+
|
|
35
|
+
if (!prob) {
|
|
36
|
+
for (const parse of this.options.parsers) {
|
|
37
|
+
const resp = parse(input)
|
|
38
|
+
|
|
39
|
+
if (!resp.length) continue
|
|
40
|
+
|
|
41
|
+
problems.push(...resp)
|
|
42
|
+
break
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (!problems.length && this.enableFallback) {
|
|
46
|
+
problems.push(new Problem({
|
|
47
|
+
...this.fallback,
|
|
48
|
+
'errorObject': input,
|
|
49
|
+
'stack': (typeof input === 'object' && input !== null && 'stack' in input && typeof input.stack === 'string') ? input.stack : undefined
|
|
50
|
+
}))
|
|
51
|
+
}
|
|
52
|
+
} else {
|
|
53
|
+
problems.push(...prob)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
for (const p of problems) {
|
|
57
|
+
if (!p.middleware) p.middleware = this.name
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
return problems
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
fallback: ProblemOpts = otherErrors.unknown
|
|
64
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { NextFunction, Request, Response } from 'express'
|
|
2
|
+
import type { PartialMiddlewareOptions } from '../typings/middleware.js'
|
|
3
|
+
import { MiddlewareBase } from './base.js'
|
|
4
|
+
import { Problem } from '../problem.js'
|
|
5
|
+
import { codes4xx, otherErrors } from '../defaults/index.js'
|
|
6
|
+
import events from '../util/events.js'
|
|
7
|
+
import { defaultInstance } from '../util/defaults.js'
|
|
8
|
+
|
|
9
|
+
export class ExpressMiddleware extends MiddlewareBase {
|
|
10
|
+
name = 'express'
|
|
11
|
+
|
|
12
|
+
middleware = (error: unknown, req: Request, res: Response, next: NextFunction) => {
|
|
13
|
+
this.parse(error)
|
|
14
|
+
.then(problems => {
|
|
15
|
+
for (const problem of problems) {
|
|
16
|
+
if (problem.instance === defaultInstance) {
|
|
17
|
+
problem.instance = req.originalUrl
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
events.emit(problems)
|
|
22
|
+
|
|
23
|
+
res
|
|
24
|
+
.contentType('application/problem+json')
|
|
25
|
+
.status(problems[0]?.status ?? 500)
|
|
26
|
+
.json(problems.map(val => val.toObject()))
|
|
27
|
+
})
|
|
28
|
+
.catch(err => {
|
|
29
|
+
res
|
|
30
|
+
.contentType('application/problem+json')
|
|
31
|
+
.status(500)
|
|
32
|
+
.json([
|
|
33
|
+
new Problem({
|
|
34
|
+
...otherErrors.unknown,
|
|
35
|
+
'instance': req.originalUrl,
|
|
36
|
+
'status': 500,
|
|
37
|
+
'stack': err?.stack,
|
|
38
|
+
'errorObject': err,
|
|
39
|
+
}).toObject()
|
|
40
|
+
])
|
|
41
|
+
|
|
42
|
+
throw err
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* This function applies the middleware to your Express application. Put this at the very end of your middleware/routes.
|
|
48
|
+
* If you want to also handle 404 errors, check out the notFound middleware function.
|
|
49
|
+
* @example app.use(middleware.use())
|
|
50
|
+
*/
|
|
51
|
+
use = () => this.middleware
|
|
52
|
+
|
|
53
|
+
constructor(options?: PartialMiddlewareOptions) {
|
|
54
|
+
super({
|
|
55
|
+
'parsers': []
|
|
56
|
+
}, options)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Put this right before the middleware.use() to catch all 404 errors and respond with a Problem instead of the default Express response
|
|
61
|
+
* @example app.use(middleware.notFound)
|
|
62
|
+
*/
|
|
63
|
+
notFound = (req: Request, res: Response, next: NextFunction) => {
|
|
64
|
+
const error = new Problem({
|
|
65
|
+
...codes4xx[404],
|
|
66
|
+
'instance': req.originalUrl,
|
|
67
|
+
'detail': `No API endpoints exist on ${req.url} for request method ${req.method}`
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
return next(error)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { otherErrors } from '../defaults/others.js'
|
|
2
|
+
import { Problem } from '../problem.js'
|
|
3
|
+
import type { Parser } from '../typings/parser.js'
|
|
4
|
+
import { getProblems } from '../util/getProblems.js'
|
|
5
|
+
import { getHttpError } from '../util/misc.js'
|
|
6
|
+
import type { AxiosError } from 'axios'
|
|
7
|
+
|
|
8
|
+
function isAxiosError<T = unknown, D = unknown>(payload: unknown): payload is AxiosError<T, D> {
|
|
9
|
+
return typeof payload === 'object' && payload !== null && 'isAxiosError' in payload && payload.isAxiosError === true
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
const parse: Parser = (input) => {
|
|
14
|
+
if (typeof input !== 'object' || input == null) return []
|
|
15
|
+
if (!isAxiosError(input)) return []
|
|
16
|
+
const request = input.request
|
|
17
|
+
|
|
18
|
+
if (input?.response?.data) {
|
|
19
|
+
const problems = getProblems(input?.response?.data)
|
|
20
|
+
if (problems?.length) return problems
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
if (input?.response) {
|
|
24
|
+
const opts = getHttpError(input.response.status)
|
|
25
|
+
if (opts) return [new Problem({
|
|
26
|
+
...opts,
|
|
27
|
+
'instance': input?.config?.url,
|
|
28
|
+
'stack': input?.stack,
|
|
29
|
+
'errorObject': input
|
|
30
|
+
})]
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// TODO: Fix this, this seems bad
|
|
34
|
+
if (request) {
|
|
35
|
+
const isNode = typeof process !== 'undefined' && process.versions && process.versions.node
|
|
36
|
+
const isBrowser = typeof window !== 'undefined' && typeof window.document !== 'undefined'
|
|
37
|
+
|
|
38
|
+
if (isBrowser && request instanceof XMLHttpRequest) {
|
|
39
|
+
return [new Problem({
|
|
40
|
+
...otherErrors.networkError,
|
|
41
|
+
'instance': input?.config?.url,
|
|
42
|
+
'stack': input?.stack,
|
|
43
|
+
'errorObject': input
|
|
44
|
+
})]
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Probably a ClientRequest
|
|
48
|
+
if (isNode && 'pipe' in request && 'destroy' in request) {
|
|
49
|
+
return [new Problem({
|
|
50
|
+
...otherErrors.networkError,
|
|
51
|
+
'instance': input?.config?.url,
|
|
52
|
+
'stack': input?.stack,
|
|
53
|
+
'errorObject': input
|
|
54
|
+
})]
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return []
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export default parse
|