1 | export interface FeathersErrorJSON {
|
2 | name: string
|
3 | message: string
|
4 | code: number
|
5 | className: string
|
6 | data?: any
|
7 | errors?: any
|
8 | }
|
9 |
|
10 | export type DynamicError = Error & { [key: string]: any }
|
11 | export type ErrorMessage = null | string | DynamicError | { [key: string]: any } | any[]
|
12 |
|
13 | interface ErrorProperties extends Omit<FeathersErrorJSON, 'message'> {
|
14 | type: string
|
15 | }
|
16 |
|
17 | export class FeathersError extends Error {
|
18 | readonly type: string
|
19 | readonly code: number
|
20 | readonly className: string
|
21 | readonly data: any
|
22 | readonly errors: any
|
23 |
|
24 | constructor(err: ErrorMessage, name: string, code: number, className: string, _data: any) {
|
25 | let msg = typeof err === 'string' ? err : 'Error'
|
26 | const properties: ErrorProperties = {
|
27 | name,
|
28 | code,
|
29 | className,
|
30 | type: 'FeathersError'
|
31 | }
|
32 |
|
33 | if (Array.isArray(_data)) {
|
34 | properties.data = _data
|
35 | } else if (typeof err === 'object' || _data !== undefined) {
|
36 | const { message, errors, ...rest } = err !== null && typeof err === 'object' ? err : _data
|
37 |
|
38 | msg = message || msg
|
39 | properties.errors = errors
|
40 | properties.data = rest
|
41 | }
|
42 |
|
43 | super(msg)
|
44 | Object.assign(this, properties)
|
45 | }
|
46 |
|
47 | toJSON() {
|
48 | const result: FeathersErrorJSON = {
|
49 | name: this.name,
|
50 | message: this.message,
|
51 | code: this.code,
|
52 | className: this.className
|
53 | }
|
54 |
|
55 | if (this.data !== undefined) {
|
56 | result.data = this.data
|
57 | }
|
58 |
|
59 | if (this.errors !== undefined) {
|
60 | result.errors = this.errors
|
61 | }
|
62 |
|
63 | return result
|
64 | }
|
65 | }
|
66 |
|
67 | export class BadRequest extends FeathersError {
|
68 | constructor(message?: ErrorMessage, data?: any) {
|
69 | super(message, 'BadRequest', 400, 'bad-request', data)
|
70 | }
|
71 | }
|
72 |
|
73 |
|
74 | export class NotAuthenticated extends FeathersError {
|
75 | constructor(message?: ErrorMessage, data?: any) {
|
76 | super(message, 'NotAuthenticated', 401, 'not-authenticated', data)
|
77 | }
|
78 | }
|
79 |
|
80 |
|
81 | export class PaymentError extends FeathersError {
|
82 | constructor(message?: ErrorMessage, data?: any) {
|
83 | super(message, 'PaymentError', 402, 'payment-error', data)
|
84 | }
|
85 | }
|
86 |
|
87 |
|
88 | export class Forbidden extends FeathersError {
|
89 | constructor(message?: ErrorMessage, data?: any) {
|
90 | super(message, 'Forbidden', 403, 'forbidden', data)
|
91 | }
|
92 | }
|
93 |
|
94 |
|
95 | export class NotFound extends FeathersError {
|
96 | constructor(message?: ErrorMessage, data?: any) {
|
97 | super(message, 'NotFound', 404, 'not-found', data)
|
98 | }
|
99 | }
|
100 |
|
101 |
|
102 | export class MethodNotAllowed extends FeathersError {
|
103 | constructor(message?: ErrorMessage, data?: any) {
|
104 | super(message, 'MethodNotAllowed', 405, 'method-not-allowed', data)
|
105 | }
|
106 | }
|
107 |
|
108 |
|
109 | export class NotAcceptable extends FeathersError {
|
110 | constructor(message?: ErrorMessage, data?: any) {
|
111 | super(message, 'NotAcceptable', 406, 'not-acceptable', data)
|
112 | }
|
113 | }
|
114 |
|
115 |
|
116 | export class Timeout extends FeathersError {
|
117 | constructor(message?: ErrorMessage, data?: any) {
|
118 | super(message, 'Timeout', 408, 'timeout', data)
|
119 | }
|
120 | }
|
121 |
|
122 |
|
123 | export class Conflict extends FeathersError {
|
124 | constructor(message?: ErrorMessage, data?: any) {
|
125 | super(message, 'Conflict', 409, 'conflict', data)
|
126 | }
|
127 | }
|
128 |
|
129 |
|
130 | export class Gone extends FeathersError {
|
131 | constructor(message?: ErrorMessage, data?: any) {
|
132 | super(message, 'Gone', 410, 'gone', data)
|
133 | }
|
134 | }
|
135 |
|
136 |
|
137 | export class LengthRequired extends FeathersError {
|
138 | constructor(message?: ErrorMessage, data?: any) {
|
139 | super(message, 'LengthRequired', 411, 'length-required', data)
|
140 | }
|
141 | }
|
142 |
|
143 |
|
144 | export class Unprocessable extends FeathersError {
|
145 | constructor(message?: ErrorMessage, data?: any) {
|
146 | super(message, 'Unprocessable', 422, 'unprocessable', data)
|
147 | }
|
148 | }
|
149 |
|
150 |
|
151 | export class TooManyRequests extends FeathersError {
|
152 | constructor(message?: ErrorMessage, data?: any) {
|
153 | super(message, 'TooManyRequests', 429, 'too-many-requests', data)
|
154 | }
|
155 | }
|
156 |
|
157 |
|
158 | export class GeneralError extends FeathersError {
|
159 | constructor(message?: ErrorMessage, data?: any) {
|
160 | super(message, 'GeneralError', 500, 'general-error', data)
|
161 | }
|
162 | }
|
163 |
|
164 |
|
165 | export class NotImplemented extends FeathersError {
|
166 | constructor(message?: ErrorMessage, data?: any) {
|
167 | super(message, 'NotImplemented', 501, 'not-implemented', data)
|
168 | }
|
169 | }
|
170 |
|
171 |
|
172 | export class BadGateway extends FeathersError {
|
173 | constructor(message?: ErrorMessage, data?: any) {
|
174 | super(message, 'BadGateway', 502, 'bad-gateway', data)
|
175 | }
|
176 | }
|
177 |
|
178 |
|
179 | export class Unavailable extends FeathersError {
|
180 | constructor(message?: ErrorMessage, data?: any) {
|
181 | super(message, 'Unavailable', 503, 'unavailable', data)
|
182 | }
|
183 | }
|
184 |
|
185 | export interface Errors {
|
186 | FeathersError: FeathersError
|
187 | BadRequest: BadRequest
|
188 | NotAuthenticated: NotAuthenticated
|
189 | PaymentError: PaymentError
|
190 | Forbidden: Forbidden
|
191 | NotFound: NotFound
|
192 | MethodNotAllowed: MethodNotAllowed
|
193 | NotAcceptable: NotAcceptable
|
194 | Timeout: Timeout
|
195 | Conflict: Conflict
|
196 | LengthRequired: LengthRequired
|
197 | Unprocessable: Unprocessable
|
198 | TooManyRequests: TooManyRequests
|
199 | GeneralError: GeneralError
|
200 | NotImplemented: NotImplemented
|
201 | BadGateway: BadGateway
|
202 | Unavailable: Unavailable
|
203 | 400: BadRequest
|
204 | 401: NotAuthenticated
|
205 | 402: PaymentError
|
206 | 403: Forbidden
|
207 | 404: NotFound
|
208 | 405: MethodNotAllowed
|
209 | 406: NotAcceptable
|
210 | 408: Timeout
|
211 | 409: Conflict
|
212 | 411: LengthRequired
|
213 | 422: Unprocessable
|
214 | 429: TooManyRequests
|
215 | 500: GeneralError
|
216 | 501: NotImplemented
|
217 | 502: BadGateway
|
218 | 503: Unavailable
|
219 | }
|
220 |
|
221 | export const errors = {
|
222 | FeathersError,
|
223 | BadRequest,
|
224 | NotAuthenticated,
|
225 | PaymentError,
|
226 | Forbidden,
|
227 | NotFound,
|
228 | MethodNotAllowed,
|
229 | NotAcceptable,
|
230 | Timeout,
|
231 | Conflict,
|
232 | LengthRequired,
|
233 | Unprocessable,
|
234 | TooManyRequests,
|
235 | GeneralError,
|
236 | NotImplemented,
|
237 | BadGateway,
|
238 | Unavailable,
|
239 | 400: BadRequest,
|
240 | 401: NotAuthenticated,
|
241 | 402: PaymentError,
|
242 | 403: Forbidden,
|
243 | 404: NotFound,
|
244 | 405: MethodNotAllowed,
|
245 | 406: NotAcceptable,
|
246 | 408: Timeout,
|
247 | 409: Conflict,
|
248 | 410: Gone,
|
249 | 411: LengthRequired,
|
250 | 422: Unprocessable,
|
251 | 429: TooManyRequests,
|
252 | 500: GeneralError,
|
253 | 501: NotImplemented,
|
254 | 502: BadGateway,
|
255 | 503: Unavailable
|
256 | }
|
257 |
|
258 | export function convert(error: any) {
|
259 | if (!error) {
|
260 | return error
|
261 | }
|
262 |
|
263 | const FeathersError = (errors as any)[error.name]
|
264 | const result = FeathersError
|
265 | ? new FeathersError(error.message, error.data)
|
266 | : new Error(error.message || error)
|
267 |
|
268 | if (typeof error === 'object') {
|
269 | Object.assign(result, error)
|
270 | }
|
271 |
|
272 | return result
|
273 | }
|