UNPKG

6.4 kBJavaScriptView Raw
1const debug = require('debug')('@feathersjs/errors');
2
3function FeathersError (msg, name, code, className, data) {
4 msg = msg || 'Error';
5
6 let errors;
7 let message;
8 let newData;
9
10 if (msg instanceof Error) {
11 message = msg.message || 'Error';
12
13 // NOTE (EK): This is typically to handle validation errors
14 if (msg.errors) {
15 errors = msg.errors;
16 }
17 } else if (typeof msg === 'object') { // Support plain old objects
18 message = msg.message || 'Error';
19 data = msg;
20 } else { // message is just a string
21 message = msg;
22 }
23
24 if (data) {
25 // NOTE(EK): To make sure that we are not messing
26 // with immutable data, just make a copy.
27 // https://github.com/feathersjs/errors/issues/19
28 newData = JSON.parse(JSON.stringify(data));
29
30 if (newData.errors) {
31 errors = newData.errors;
32 delete newData.errors;
33 } else if (data.errors) {
34 // The errors property from data could be
35 // stripped away while cloning resulting newData not to have it
36 // For example: when cloning arrays this property
37 errors = JSON.parse(JSON.stringify(data.errors));
38 }
39 }
40
41 // NOTE (EK): Babel doesn't support this so
42 // we have to pass in the class name manually.
43 // this.name = this.constructor.name;
44 this.type = 'FeathersError';
45 this.name = name;
46 this.message = message;
47 this.code = code;
48 this.className = className;
49 this.data = newData;
50 this.errors = errors || {};
51
52 debug(`${this.name}(${this.code}): ${this.message}`);
53 debug(this.errors);
54
55 if (Error.captureStackTrace) {
56 Error.captureStackTrace(this, FeathersError);
57 } else {
58 this.stack = (new Error()).stack;
59 }
60}
61
62function inheritsFrom (Child, Parent) {
63 Child.prototype = Object.create(Parent.prototype);
64 Child.prototype.constructor = Child;
65}
66
67inheritsFrom(FeathersError, Error);
68
69// NOTE (EK): A little hack to get around `message` not
70// being included in the default toJSON call.
71Object.defineProperty(FeathersError.prototype, 'toJSON', {
72 value: function () {
73 return {
74 name: this.name,
75 message: this.message,
76 code: this.code,
77 className: this.className,
78 data: this.data,
79 errors: this.errors
80 };
81 }
82});
83
84// 400 - Bad Request
85function BadRequest (message, data) {
86 FeathersError.call(this, message, 'BadRequest', 400, 'bad-request', data);
87}
88
89inheritsFrom(BadRequest, FeathersError);
90
91// 401 - Not Authenticated
92function NotAuthenticated (message, data) {
93 FeathersError.call(this, message, 'NotAuthenticated', 401, 'not-authenticated', data);
94}
95
96inheritsFrom(NotAuthenticated, FeathersError);
97
98// 402 - Payment Error
99function PaymentError (message, data) {
100 FeathersError.call(this, message, 'PaymentError', 402, 'payment-error', data);
101}
102
103inheritsFrom(PaymentError, FeathersError);
104
105// 403 - Forbidden
106function Forbidden (message, data) {
107 FeathersError.call(this, message, 'Forbidden', 403, 'forbidden', data);
108}
109
110inheritsFrom(Forbidden, FeathersError);
111
112// 404 - Not Found
113function NotFound (message, data) {
114 FeathersError.call(this, message, 'NotFound', 404, 'not-found', data);
115}
116
117inheritsFrom(NotFound, FeathersError);
118
119// 405 - Method Not Allowed
120function MethodNotAllowed (message, data) {
121 FeathersError.call(this, message, 'MethodNotAllowed', 405, 'method-not-allowed', data);
122}
123
124inheritsFrom(MethodNotAllowed, FeathersError);
125
126// 406 - Not Acceptable
127function NotAcceptable (message, data) {
128 FeathersError.call(this, message, 'NotAcceptable', 406, 'not-acceptable', data);
129}
130
131inheritsFrom(NotAcceptable, FeathersError);
132
133// 408 - Timeout
134function Timeout (message, data) {
135 FeathersError.call(this, message, 'Timeout', 408, 'timeout', data);
136}
137
138inheritsFrom(Timeout, FeathersError);
139
140// 409 - Conflict
141function Conflict (message, data) {
142 FeathersError.call(this, message, 'Conflict', 409, 'conflict', data);
143}
144
145inheritsFrom(Conflict, FeathersError);
146
147// 410 - Gone
148function Gone (message, data) {
149 FeathersError(this, message, 'Gone', 410, 'gone', data);
150}
151
152inheritsFrom(Gone, FeathersError);
153
154// 411 - Length Required
155function LengthRequired (message, data) {
156 FeathersError.call(this, message, 'LengthRequired', 411, 'length-required', data);
157}
158
159inheritsFrom(LengthRequired, FeathersError);
160
161// 422 Unprocessable
162function Unprocessable (message, data) {
163 FeathersError.call(this, message, 'Unprocessable', 422, 'unprocessable', data);
164}
165
166inheritsFrom(Unprocessable, FeathersError);
167
168// 429 Too Many Requests
169function TooManyRequests (message, data) {
170 FeathersError.call(this, message, 'TooManyRequests', 429, 'too-many-requests', data);
171}
172
173inheritsFrom(TooManyRequests, FeathersError);
174
175// 500 - General Error
176function GeneralError (message, data) {
177 FeathersError.call(this, message, 'GeneralError', 500, 'general-error', data);
178}
179
180inheritsFrom(GeneralError, FeathersError);
181
182// 501 - Not Implemented
183function NotImplemented (message, data) {
184 FeathersError.call(this, message, 'NotImplemented', 501, 'not-implemented', data);
185}
186
187inheritsFrom(NotImplemented, FeathersError);
188
189// 502 - Bad Gateway
190function BadGateway (message, data) {
191 FeathersError.call(this, message, 'BadGateway', 502, 'bad-gateway', data);
192}
193
194inheritsFrom(BadGateway, FeathersError);
195
196// 503 - Unavailable
197function Unavailable (message, data) {
198 FeathersError.call(this, message, 'Unavailable', 503, 'unavailable', data);
199}
200
201inheritsFrom(Unavailable, FeathersError);
202
203const errors = {
204 FeathersError,
205 BadRequest,
206 NotAuthenticated,
207 PaymentError,
208 Forbidden,
209 NotFound,
210 MethodNotAllowed,
211 NotAcceptable,
212 Timeout,
213 Conflict,
214 Gone,
215 LengthRequired,
216 Unprocessable,
217 TooManyRequests,
218 GeneralError,
219 NotImplemented,
220 BadGateway,
221 Unavailable,
222 400: BadRequest,
223 401: NotAuthenticated,
224 402: PaymentError,
225 403: Forbidden,
226 404: NotFound,
227 405: MethodNotAllowed,
228 406: NotAcceptable,
229 408: Timeout,
230 409: Conflict,
231 410: Gone,
232 411: LengthRequired,
233 422: Unprocessable,
234 429: TooManyRequests,
235 500: GeneralError,
236 501: NotImplemented,
237 502: BadGateway,
238 503: Unavailable
239};
240
241function convert (error) {
242 if (!error) {
243 return error;
244 }
245
246 const FeathersError = errors[error.name];
247 const result = FeathersError
248 ? new FeathersError(error.message, error.data)
249 : new Error(error.message || error);
250
251 if (typeof error === 'object') {
252 Object.assign(result, error);
253 }
254
255 return result;
256}
257
258module.exports = Object.assign({ convert }, errors);