@naturalcycles/js-lib 14.172.0 → 14.173.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/dist/error/assert.d.ts +0 -4
- package/dist/error/assert.js +7 -14
- package/dist/error/error.util.d.ts +80 -1
- package/dist/error/error.util.js +117 -2
- package/dist/error/try.d.ts +0 -9
- package/dist/error/try.js +6 -19
- package/dist/http/fetcher.d.ts +1 -1
- package/dist/http/fetcher.js +3 -4
- package/dist/index.d.ts +0 -3
- package/dist/index.js +0 -3
- package/dist/promise/pTimeout.d.ts +1 -4
- package/dist/promise/pTimeout.js +2 -9
- package/dist/string/json.util.js +2 -2
- package/dist-esm/error/assert.js +1 -7
- package/dist-esm/error/error.util.js +110 -1
- package/dist-esm/error/try.js +1 -13
- package/dist-esm/http/fetcher.js +2 -3
- package/dist-esm/index.js +0 -3
- package/dist-esm/promise/pTimeout.js +1 -7
- package/dist-esm/string/json.util.js +1 -1
- package/package.json +1 -1
- package/src/error/assert.ts +1 -8
- package/src/error/error.util.ts +163 -1
- package/src/error/try.ts +1 -18
- package/src/http/fetcher.ts +8 -3
- package/src/index.ts +0 -3
- package/src/promise/pTimeout.ts +1 -8
- package/src/string/json.util.ts +1 -1
- package/dist/error/app.error.d.ts +0 -31
- package/dist/error/app.error.js +0 -57
- package/dist/error/httpRequestError.d.ts +0 -28
- package/dist/error/httpRequestError.js +0 -32
- package/dist/error/jsonParseError.d.ts +0 -11
- package/dist/error/jsonParseError.js +0 -14
- package/dist-esm/error/app.error.js +0 -53
- package/dist-esm/error/httpRequestError.js +0 -28
- package/dist-esm/error/jsonParseError.js +0 -10
- package/src/error/app.error.ts +0 -81
- package/src/error/httpRequestError.ts +0 -38
- package/src/error/jsonParseError.ts +0 -20
package/dist/error/assert.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { ErrorData, ErrorObject } from '..';
|
|
2
2
|
import { Class } from '..';
|
|
3
|
-
import { AppError } from './app.error';
|
|
4
3
|
/**
|
|
5
4
|
* Evaluates the `condition` (casts it to Boolean).
|
|
6
5
|
* Expects it to be truthy, otherwise throws AppError.
|
|
@@ -43,6 +42,3 @@ export declare function _assertIsErrorObject<DATA_TYPE extends ErrorData = Error
|
|
|
43
42
|
export declare function _assertIsString(v: any, message?: string): asserts v is string;
|
|
44
43
|
export declare function _assertIsNumber(v: any, message?: string): asserts v is number;
|
|
45
44
|
export declare function _assertTypeOf<T>(v: any, expectedType: string, message?: string): asserts v is T;
|
|
46
|
-
export declare class AssertionError extends AppError {
|
|
47
|
-
constructor(message: string, data?: ErrorData);
|
|
48
|
-
}
|
package/dist/error/assert.js
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports._assertTypeOf = exports._assertIsNumber = exports._assertIsString = exports._assertIsErrorObject = exports._assertErrorClassOrRethrow = exports._assertIsError = exports._assertDeepEquals = exports._assertEquals = exports._assert = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
|
-
const app_error_1 = require("./app.error");
|
|
6
5
|
/**
|
|
7
6
|
* Evaluates the `condition` (casts it to Boolean).
|
|
8
7
|
* Expects it to be truthy, otherwise throws AppError.
|
|
@@ -21,7 +20,7 @@ const app_error_1 = require("./app.error");
|
|
|
21
20
|
function _assert(condition, // will be evaluated as Boolean
|
|
22
21
|
message, errorData) {
|
|
23
22
|
if (!condition) {
|
|
24
|
-
throw new AssertionError(message || 'see stacktrace', {
|
|
23
|
+
throw new __1.AssertionError(message || 'see stacktrace', {
|
|
25
24
|
userFriendly: true,
|
|
26
25
|
...errorData,
|
|
27
26
|
});
|
|
@@ -40,7 +39,7 @@ function _assertEquals(actual, expected, message, errorData) {
|
|
|
40
39
|
['not equal', `expected: ${(0, __1._stringifyAny)(expected)}`, `got : ${(0, __1._stringifyAny)(actual)}`]
|
|
41
40
|
.filter(Boolean)
|
|
42
41
|
.join('\n');
|
|
43
|
-
throw new AssertionError(msg, {
|
|
42
|
+
throw new __1.AssertionError(msg, {
|
|
44
43
|
userFriendly: true,
|
|
45
44
|
...errorData,
|
|
46
45
|
});
|
|
@@ -63,7 +62,7 @@ function _assertDeepEquals(actual, expected, message, errorData) {
|
|
|
63
62
|
]
|
|
64
63
|
.filter(Boolean)
|
|
65
64
|
.join('\n');
|
|
66
|
-
throw new AssertionError(msg, {
|
|
65
|
+
throw new __1.AssertionError(msg, {
|
|
67
66
|
userFriendly: true,
|
|
68
67
|
...errorData,
|
|
69
68
|
});
|
|
@@ -76,7 +75,7 @@ function _assertIsError(err, errorClass = Error) {
|
|
|
76
75
|
`expected to be instanceof ${errorClass.name}`,
|
|
77
76
|
`actual typeof: ${typeof err}`,
|
|
78
77
|
].join('\n');
|
|
79
|
-
throw new AssertionError(msg, {
|
|
78
|
+
throw new __1.AssertionError(msg, {
|
|
80
79
|
userFriendly: true,
|
|
81
80
|
});
|
|
82
81
|
}
|
|
@@ -97,7 +96,7 @@ exports._assertErrorClassOrRethrow = _assertErrorClassOrRethrow;
|
|
|
97
96
|
function _assertIsErrorObject(obj) {
|
|
98
97
|
if (!(0, __1._isErrorObject)(obj)) {
|
|
99
98
|
const msg = [`expected to be ErrorObject`, `actual typeof: ${typeof obj}`].join('\n');
|
|
100
|
-
throw new AssertionError(msg, {
|
|
99
|
+
throw new __1.AssertionError(msg, {
|
|
101
100
|
userFriendly: true,
|
|
102
101
|
});
|
|
103
102
|
}
|
|
@@ -118,15 +117,9 @@ function _assertTypeOf(v, expectedType, message) {
|
|
|
118
117
|
`expected: ${expectedType}`,
|
|
119
118
|
`got : ${typeof v}`,
|
|
120
119
|
].join('\n');
|
|
121
|
-
throw new AssertionError(msg, {
|
|
120
|
+
throw new __1.AssertionError(msg, {
|
|
122
121
|
userFriendly: true,
|
|
123
122
|
});
|
|
124
123
|
}
|
|
125
124
|
}
|
|
126
125
|
exports._assertTypeOf = _assertTypeOf;
|
|
127
|
-
class AssertionError extends app_error_1.AppError {
|
|
128
|
-
constructor(message, data) {
|
|
129
|
-
super(message, data, { name: 'AssertionError' });
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
exports.AssertionError = AssertionError;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { ErrorData, ErrorObject, BackendErrorResponseObject, Class, HttpRequestErrorData, ErrorLike } from '..';
|
|
2
|
-
import { AppError } from '..';
|
|
3
2
|
/**
|
|
4
3
|
* Useful to ensure that error in `catch (err) { ... }`
|
|
5
4
|
* is indeed an Error (and not e.g `string` or `undefined`).
|
|
@@ -56,3 +55,83 @@ export declare function _isErrorLike(o: any): o is ErrorLike;
|
|
|
56
55
|
* }
|
|
57
56
|
*/
|
|
58
57
|
export declare function _errorDataAppend<ERR>(err: ERR, data?: ErrorData): ERR;
|
|
58
|
+
/**
|
|
59
|
+
* Base class for all our (not system) errors.
|
|
60
|
+
*
|
|
61
|
+
* message - "technical" message. Frontend decides to show it or not.
|
|
62
|
+
* data - optional "any" payload.
|
|
63
|
+
* data.userFriendly - if present, will be displayed to the User as is.
|
|
64
|
+
*
|
|
65
|
+
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
66
|
+
*/
|
|
67
|
+
export declare class AppError<DATA_TYPE extends ErrorData = ErrorData> extends Error {
|
|
68
|
+
data: DATA_TYPE;
|
|
69
|
+
/**
|
|
70
|
+
* `cause` here is normalized to be an ErrorObject
|
|
71
|
+
*/
|
|
72
|
+
cause?: ErrorObject;
|
|
73
|
+
constructor(message: string, data?: DATA_TYPE, opt?: AppErrorOptions);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Extra options for AppError constructor.
|
|
77
|
+
*/
|
|
78
|
+
export interface AppErrorOptions {
|
|
79
|
+
/**
|
|
80
|
+
* Overrides Error.name and Error.constructor.name
|
|
81
|
+
*/
|
|
82
|
+
name?: string;
|
|
83
|
+
/**
|
|
84
|
+
* Sets Error.cause.
|
|
85
|
+
* It is transformed with _anyToErrorObject()
|
|
86
|
+
*/
|
|
87
|
+
cause?: any;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Error that is thrown when Http Request was made and returned an error.
|
|
91
|
+
* Thrown by, for example, Fetcher.
|
|
92
|
+
*
|
|
93
|
+
* On the Frontend this Error class represents the error when calling the API,
|
|
94
|
+
* contains all the necessary request and response information.
|
|
95
|
+
*
|
|
96
|
+
* On the Backend, similarly, it represents the error when calling some 3rd-party API
|
|
97
|
+
* (backend-to-backend call).
|
|
98
|
+
* On the Backend it often propagates all the way to the Backend error handler,
|
|
99
|
+
* where it would be wrapped in BackendErrorResponseObject.
|
|
100
|
+
*
|
|
101
|
+
* Please note that `ErrorData.backendResponseStatusCode` is NOT exactly the same as
|
|
102
|
+
* `HttpRequestErrorData.responseStatusCode`.
|
|
103
|
+
* E.g 3rd-party call may return 401, but our Backend will still wrap it into an 500 error
|
|
104
|
+
* (by default).
|
|
105
|
+
*/
|
|
106
|
+
export declare class HttpRequestError extends AppError<HttpRequestErrorData> {
|
|
107
|
+
constructor(message: string, data: HttpRequestErrorData, opt?: AppErrorOptions);
|
|
108
|
+
/**
|
|
109
|
+
* Cause is strictly-defined for HttpRequestError,
|
|
110
|
+
* so it always has a cause.
|
|
111
|
+
* (for dev convenience)
|
|
112
|
+
*/
|
|
113
|
+
cause: ErrorObject;
|
|
114
|
+
}
|
|
115
|
+
export declare class AssertionError extends AppError {
|
|
116
|
+
constructor(message: string, data?: ErrorData);
|
|
117
|
+
}
|
|
118
|
+
export interface JsonParseErrorData extends ErrorData {
|
|
119
|
+
/**
|
|
120
|
+
* Original text that failed to get parsed.
|
|
121
|
+
*/
|
|
122
|
+
text?: string;
|
|
123
|
+
}
|
|
124
|
+
export declare class JsonParseError extends AppError<JsonParseErrorData> {
|
|
125
|
+
constructor(data: JsonParseErrorData);
|
|
126
|
+
}
|
|
127
|
+
export declare class TimeoutError extends AppError {
|
|
128
|
+
constructor(message: string, data?: ErrorData, opt?: AppErrorOptions);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* It is thrown when Error was expected, but didn't happen
|
|
132
|
+
* ("pass" happened instead).
|
|
133
|
+
* "Pass" means "no error".
|
|
134
|
+
*/
|
|
135
|
+
export declare class UnexpectedPassError extends AppError {
|
|
136
|
+
constructor();
|
|
137
|
+
}
|
package/dist/error/error.util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._errorDataAppend = exports._isErrorLike = exports._isErrorObject = exports._isHttpRequestErrorObject = exports._isBackendErrorResponseObject = exports._errorSnippet = exports._errorObjectToError = exports._errorLikeToErrorObject = exports._anyToErrorObject = exports._anyToError = void 0;
|
|
3
|
+
exports.UnexpectedPassError = exports.TimeoutError = exports.JsonParseError = exports.AssertionError = exports.HttpRequestError = exports.AppError = exports._errorDataAppend = exports._isErrorLike = exports._isErrorObject = exports._isHttpRequestErrorObject = exports._isBackendErrorResponseObject = exports._errorSnippet = exports._errorObjectToError = exports._errorLikeToErrorObject = exports._anyToErrorObject = exports._anyToError = void 0;
|
|
4
4
|
const __1 = require("..");
|
|
5
5
|
/**
|
|
6
6
|
* Useful to ensure that error in `catch (err) { ... }`
|
|
@@ -106,7 +106,7 @@ function _errorObjectToError(o, errorClass = Error) {
|
|
|
106
106
|
value: o.stack,
|
|
107
107
|
});
|
|
108
108
|
}
|
|
109
|
-
if (!(err instanceof
|
|
109
|
+
if (!(err instanceof AppError)) {
|
|
110
110
|
// Following actions are only needed for non-AppError-like errors
|
|
111
111
|
Object.defineProperties(err, {
|
|
112
112
|
name: {
|
|
@@ -225,3 +225,118 @@ function _errorDataAppend(err, data) {
|
|
|
225
225
|
return err;
|
|
226
226
|
}
|
|
227
227
|
exports._errorDataAppend = _errorDataAppend;
|
|
228
|
+
/**
|
|
229
|
+
* Base class for all our (not system) errors.
|
|
230
|
+
*
|
|
231
|
+
* message - "technical" message. Frontend decides to show it or not.
|
|
232
|
+
* data - optional "any" payload.
|
|
233
|
+
* data.userFriendly - if present, will be displayed to the User as is.
|
|
234
|
+
*
|
|
235
|
+
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
236
|
+
*/
|
|
237
|
+
class AppError extends Error {
|
|
238
|
+
constructor(message, data = {}, opt = {}) {
|
|
239
|
+
super(message);
|
|
240
|
+
const { name = this.constructor.name, cause } = opt;
|
|
241
|
+
Object.defineProperties(this, {
|
|
242
|
+
name: {
|
|
243
|
+
value: name,
|
|
244
|
+
configurable: true,
|
|
245
|
+
writable: true,
|
|
246
|
+
},
|
|
247
|
+
data: {
|
|
248
|
+
value: data,
|
|
249
|
+
writable: true,
|
|
250
|
+
configurable: true,
|
|
251
|
+
enumerable: false,
|
|
252
|
+
},
|
|
253
|
+
});
|
|
254
|
+
if (cause) {
|
|
255
|
+
Object.defineProperty(this, 'cause', {
|
|
256
|
+
value: _anyToErrorObject(cause),
|
|
257
|
+
writable: true,
|
|
258
|
+
configurable: true,
|
|
259
|
+
enumerable: true, // unlike standard - setting it to true for "visibility"
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
// this is to allow changing this.constuctor.name to a non-minified version
|
|
263
|
+
Object.defineProperty(this.constructor, 'name', {
|
|
264
|
+
value: name,
|
|
265
|
+
configurable: true,
|
|
266
|
+
writable: true,
|
|
267
|
+
});
|
|
268
|
+
// todo: check if it's needed at all!
|
|
269
|
+
// if (Error.captureStackTrace) {
|
|
270
|
+
// Error.captureStackTrace(this, this.constructor)
|
|
271
|
+
// } else {
|
|
272
|
+
// Object.defineProperty(this, 'stack', {
|
|
273
|
+
// value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
274
|
+
// writable: true,
|
|
275
|
+
// configurable: true,
|
|
276
|
+
// })
|
|
277
|
+
// }
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
exports.AppError = AppError;
|
|
281
|
+
/**
|
|
282
|
+
* Error that is thrown when Http Request was made and returned an error.
|
|
283
|
+
* Thrown by, for example, Fetcher.
|
|
284
|
+
*
|
|
285
|
+
* On the Frontend this Error class represents the error when calling the API,
|
|
286
|
+
* contains all the necessary request and response information.
|
|
287
|
+
*
|
|
288
|
+
* On the Backend, similarly, it represents the error when calling some 3rd-party API
|
|
289
|
+
* (backend-to-backend call).
|
|
290
|
+
* On the Backend it often propagates all the way to the Backend error handler,
|
|
291
|
+
* where it would be wrapped in BackendErrorResponseObject.
|
|
292
|
+
*
|
|
293
|
+
* Please note that `ErrorData.backendResponseStatusCode` is NOT exactly the same as
|
|
294
|
+
* `HttpRequestErrorData.responseStatusCode`.
|
|
295
|
+
* E.g 3rd-party call may return 401, but our Backend will still wrap it into an 500 error
|
|
296
|
+
* (by default).
|
|
297
|
+
*/
|
|
298
|
+
class HttpRequestError extends AppError {
|
|
299
|
+
constructor(message, data, opt) {
|
|
300
|
+
if (data.response) {
|
|
301
|
+
Object.defineProperty(data, 'response', {
|
|
302
|
+
enumerable: false,
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
super(message, data, { ...opt, name: 'HttpRequestError' });
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
exports.HttpRequestError = HttpRequestError;
|
|
309
|
+
class AssertionError extends AppError {
|
|
310
|
+
constructor(message, data) {
|
|
311
|
+
super(message, data, { name: 'AssertionError' });
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
exports.AssertionError = AssertionError;
|
|
315
|
+
class JsonParseError extends AppError {
|
|
316
|
+
constructor(data) {
|
|
317
|
+
const message = ['Failed to parse', data.text && (0, __1._truncateMiddle)(data.text, 200)]
|
|
318
|
+
.filter(Boolean)
|
|
319
|
+
.join(': ');
|
|
320
|
+
super(message, data, { name: 'JsonParseError' });
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
exports.JsonParseError = JsonParseError;
|
|
324
|
+
class TimeoutError extends AppError {
|
|
325
|
+
constructor(message, data, opt) {
|
|
326
|
+
super(message, data, { ...opt, name: 'TimeoutError' });
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
exports.TimeoutError = TimeoutError;
|
|
330
|
+
/**
|
|
331
|
+
* It is thrown when Error was expected, but didn't happen
|
|
332
|
+
* ("pass" happened instead).
|
|
333
|
+
* "Pass" means "no error".
|
|
334
|
+
*/
|
|
335
|
+
class UnexpectedPassError extends AppError {
|
|
336
|
+
constructor() {
|
|
337
|
+
super('expected error was not thrown', {}, {
|
|
338
|
+
name: 'UnexpectedPassError',
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
exports.UnexpectedPassError = UnexpectedPassError;
|
package/dist/error/try.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Class } from '../typeFest';
|
|
2
2
|
import type { AnyFunction, ErrorDataTuple } from '../types';
|
|
3
|
-
import { AppError } from './app.error';
|
|
4
3
|
/**
|
|
5
4
|
* Calls a function, returns a Tuple of [error, value].
|
|
6
5
|
* Allows to write shorter code that avoids `try/catch`.
|
|
@@ -25,14 +24,6 @@ export declare function _try<T, ERR extends Error = Error>(fn: () => T, errorCla
|
|
|
25
24
|
* Like _try, but for Promises.
|
|
26
25
|
*/
|
|
27
26
|
export declare function pTry<T, ERR extends Error = Error>(promise: Promise<T>, errorClass?: Class<ERR>): Promise<ErrorDataTuple<Awaited<T>, ERR>>;
|
|
28
|
-
/**
|
|
29
|
-
* It is thrown when Error was expected, but didn't happen
|
|
30
|
-
* ("pass" happened instead).
|
|
31
|
-
* "Pass" means "no error".
|
|
32
|
-
*/
|
|
33
|
-
export declare class UnexpectedPassError extends AppError {
|
|
34
|
-
constructor();
|
|
35
|
-
}
|
|
36
27
|
/**
|
|
37
28
|
* Calls `fn`, expects is to throw, catches the expected error and returns.
|
|
38
29
|
* If error was NOT thrown - throws UnexpectedPassError instead.
|
package/dist/error/try.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports._expectedErrorString = exports.pExpectedErrorString = exports.pExpectedError = exports._expectedError = exports.
|
|
3
|
+
exports._expectedErrorString = exports.pExpectedErrorString = exports.pExpectedError = exports._expectedError = exports.pTry = exports._try = void 0;
|
|
4
4
|
const stringifyAny_1 = require("../string/stringifyAny");
|
|
5
|
-
const app_error_1 = require("./app.error");
|
|
6
5
|
const assert_1 = require("./assert");
|
|
6
|
+
const error_util_1 = require("./error.util");
|
|
7
7
|
/**
|
|
8
8
|
* Calls a function, returns a Tuple of [error, value].
|
|
9
9
|
* Allows to write shorter code that avoids `try/catch`.
|
|
@@ -50,19 +50,6 @@ async function pTry(promise, errorClass) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
exports.pTry = pTry;
|
|
53
|
-
/**
|
|
54
|
-
* It is thrown when Error was expected, but didn't happen
|
|
55
|
-
* ("pass" happened instead).
|
|
56
|
-
* "Pass" means "no error".
|
|
57
|
-
*/
|
|
58
|
-
class UnexpectedPassError extends app_error_1.AppError {
|
|
59
|
-
constructor() {
|
|
60
|
-
super('expected error was not thrown', {}, {
|
|
61
|
-
name: 'UnexpectedPassError',
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
exports.UnexpectedPassError = UnexpectedPassError;
|
|
66
53
|
/**
|
|
67
54
|
* Calls `fn`, expects is to throw, catches the expected error and returns.
|
|
68
55
|
* If error was NOT thrown - throws UnexpectedPassError instead.
|
|
@@ -75,10 +62,10 @@ function _expectedError(fn, errorClass) {
|
|
|
75
62
|
try {
|
|
76
63
|
fn();
|
|
77
64
|
// Unexpected!
|
|
78
|
-
throw new UnexpectedPassError();
|
|
65
|
+
throw new error_util_1.UnexpectedPassError();
|
|
79
66
|
}
|
|
80
67
|
catch (err) {
|
|
81
|
-
if (err instanceof UnexpectedPassError)
|
|
68
|
+
if (err instanceof error_util_1.UnexpectedPassError)
|
|
82
69
|
throw err; // re-throw
|
|
83
70
|
if (errorClass && !(err instanceof errorClass)) {
|
|
84
71
|
console.warn(`_expectedError expected ${errorClass.constructor.name} but got different error class`);
|
|
@@ -100,10 +87,10 @@ async function pExpectedError(promise, errorClass) {
|
|
|
100
87
|
try {
|
|
101
88
|
await promise;
|
|
102
89
|
// Unexpected!
|
|
103
|
-
throw new UnexpectedPassError();
|
|
90
|
+
throw new error_util_1.UnexpectedPassError();
|
|
104
91
|
}
|
|
105
92
|
catch (err) {
|
|
106
|
-
if (err instanceof UnexpectedPassError)
|
|
93
|
+
if (err instanceof error_util_1.UnexpectedPassError)
|
|
107
94
|
throw err; // re-throw
|
|
108
95
|
if (errorClass && !(err instanceof errorClass)) {
|
|
109
96
|
console.warn(`pExpectedError expected ${errorClass.constructor.name} but got different error class`);
|
package/dist/http/fetcher.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference lib="dom" />
|
|
2
2
|
/// <reference lib="dom.iterable" />
|
|
3
|
-
import { HttpRequestError } from '../error/
|
|
3
|
+
import { HttpRequestError } from '../error/error.util';
|
|
4
4
|
import { ErrorDataTuple } from '../types';
|
|
5
5
|
import type { FetcherAfterResponseHook, FetcherBeforeRequestHook, FetcherBeforeRetryHook, FetcherCfg, FetcherNormalizedCfg, FetcherOptions, FetcherResponse, RequestInitNormalized } from './fetcher.model';
|
|
6
6
|
/**
|
package/dist/http/fetcher.js
CHANGED
|
@@ -6,7 +6,6 @@ exports.getFetcher = exports.Fetcher = void 0;
|
|
|
6
6
|
const env_1 = require("../env");
|
|
7
7
|
const assert_1 = require("../error/assert");
|
|
8
8
|
const error_util_1 = require("../error/error.util");
|
|
9
|
-
const httpRequestError_1 = require("../error/httpRequestError");
|
|
10
9
|
const number_util_1 = require("../number/number.util");
|
|
11
10
|
const object_util_1 = require("../object/object.util");
|
|
12
11
|
const pDelay_1 = require("../promise/pDelay");
|
|
@@ -131,7 +130,7 @@ class Fetcher {
|
|
|
131
130
|
async tryFetch(opt) {
|
|
132
131
|
const res = await this.doFetch(opt);
|
|
133
132
|
if (res.err) {
|
|
134
|
-
(0, assert_1._assertErrorClassOrRethrow)(res.err,
|
|
133
|
+
(0, assert_1._assertErrorClassOrRethrow)(res.err, error_util_1.HttpRequestError);
|
|
135
134
|
return [res.err, null];
|
|
136
135
|
}
|
|
137
136
|
return [null, res.body];
|
|
@@ -174,7 +173,7 @@ class Fetcher {
|
|
|
174
173
|
// console.log(`actual request timed out in ${_since(req.started)}`)
|
|
175
174
|
// Apparently, providing a `string` reason to abort() causes Undici to throw `invalid_argument` error,
|
|
176
175
|
// so, we're wrapping it in a TimeoutError instance
|
|
177
|
-
abortController.abort(new
|
|
176
|
+
abortController.abort(new error_util_1.TimeoutError(`request timed out after ${timeoutSeconds} sec`));
|
|
178
177
|
}, timeoutSeconds * 1000);
|
|
179
178
|
}
|
|
180
179
|
if (this.cfg.logRequest) {
|
|
@@ -316,7 +315,7 @@ class Fetcher {
|
|
|
316
315
|
data: {},
|
|
317
316
|
};
|
|
318
317
|
const message = [res.fetchResponse?.status, res.signature].filter(Boolean).join(' ');
|
|
319
|
-
res.err = new
|
|
318
|
+
res.err = new error_util_1.HttpRequestError(message, (0, object_util_1._filterNullishValues)({
|
|
320
319
|
response: res.fetchResponse,
|
|
321
320
|
responseStatusCode: res.fetchResponse?.status || 0,
|
|
322
321
|
// These properties are provided to be used in e.g custom Sentry error grouping
|
package/dist/index.d.ts
CHANGED
|
@@ -14,16 +14,13 @@ export * from './decorators/memoFn';
|
|
|
14
14
|
export * from './decorators/memoFnAsync';
|
|
15
15
|
export * from './decorators/retry.decorator';
|
|
16
16
|
export * from './decorators/timeout.decorator';
|
|
17
|
-
export * from './error/app.error';
|
|
18
17
|
export * from './error/assert';
|
|
19
18
|
export * from './enum.util';
|
|
20
19
|
export * from './error/error.model';
|
|
21
20
|
export * from './error/error.util';
|
|
22
21
|
export * from './error/errorMode';
|
|
23
|
-
export * from './error/httpRequestError';
|
|
24
22
|
export * from './error/try';
|
|
25
23
|
export * from './error/tryCatch';
|
|
26
|
-
export * from './error/jsonParseError';
|
|
27
24
|
export * from './json-schema/from-data/generateJsonSchemaFromData';
|
|
28
25
|
export * from './json-schema/jsonSchema.cnst';
|
|
29
26
|
export * from './json-schema/jsonSchema.model';
|
package/dist/index.js
CHANGED
|
@@ -18,16 +18,13 @@ tslib_1.__exportStar(require("./decorators/memoFn"), exports);
|
|
|
18
18
|
tslib_1.__exportStar(require("./decorators/memoFnAsync"), exports);
|
|
19
19
|
tslib_1.__exportStar(require("./decorators/retry.decorator"), exports);
|
|
20
20
|
tslib_1.__exportStar(require("./decorators/timeout.decorator"), exports);
|
|
21
|
-
tslib_1.__exportStar(require("./error/app.error"), exports);
|
|
22
21
|
tslib_1.__exportStar(require("./error/assert"), exports);
|
|
23
22
|
tslib_1.__exportStar(require("./enum.util"), exports);
|
|
24
23
|
tslib_1.__exportStar(require("./error/error.model"), exports);
|
|
25
24
|
tslib_1.__exportStar(require("./error/error.util"), exports);
|
|
26
25
|
tslib_1.__exportStar(require("./error/errorMode"), exports);
|
|
27
|
-
tslib_1.__exportStar(require("./error/httpRequestError"), exports);
|
|
28
26
|
tslib_1.__exportStar(require("./error/try"), exports);
|
|
29
27
|
tslib_1.__exportStar(require("./error/tryCatch"), exports);
|
|
30
|
-
tslib_1.__exportStar(require("./error/jsonParseError"), exports);
|
|
31
28
|
tslib_1.__exportStar(require("./json-schema/from-data/generateJsonSchemaFromData"), exports);
|
|
32
29
|
tslib_1.__exportStar(require("./json-schema/jsonSchema.cnst"), exports);
|
|
33
30
|
tslib_1.__exportStar(require("./json-schema/jsonSchema.model"), exports);
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import { AppError, AppErrorOptions } from '../error/app.error';
|
|
2
1
|
import type { ErrorData } from '../error/error.model';
|
|
2
|
+
import { TimeoutError } from '../error/error.util';
|
|
3
3
|
import type { AnyAsyncFunction, NumberOfMilliseconds } from '../types';
|
|
4
|
-
export declare class TimeoutError extends AppError {
|
|
5
|
-
constructor(message: string, data?: ErrorData, opt?: AppErrorOptions);
|
|
6
|
-
}
|
|
7
4
|
export interface PTimeoutOptions {
|
|
8
5
|
/**
|
|
9
6
|
* Timeout in milliseconds.
|
package/dist/promise/pTimeout.js
CHANGED
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.pTimeout = exports.pTimeoutFn =
|
|
4
|
-
const app_error_1 = require("../error/app.error");
|
|
3
|
+
exports.pTimeout = exports.pTimeoutFn = void 0;
|
|
5
4
|
const error_util_1 = require("../error/error.util");
|
|
6
|
-
class TimeoutError extends app_error_1.AppError {
|
|
7
|
-
constructor(message, data, opt) {
|
|
8
|
-
super(message, data, { ...opt, name: 'TimeoutError' });
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
exports.TimeoutError = TimeoutError;
|
|
12
5
|
/**
|
|
13
6
|
* Decorates a Function with a timeout.
|
|
14
7
|
* Returns a decorated Function.
|
|
@@ -36,7 +29,7 @@ async function pTimeout(fn, opt) {
|
|
|
36
29
|
return await new Promise(async (resolve, reject) => {
|
|
37
30
|
// Prepare the timeout timer
|
|
38
31
|
const timer = setTimeout(() => {
|
|
39
|
-
const err = new TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData);
|
|
32
|
+
const err = new error_util_1.TimeoutError(`"${name}" timed out after ${timeout} ms`, opt.errorData);
|
|
40
33
|
// keep original stack
|
|
41
34
|
err.stack = fakeError.stack.replace('Error: TimeoutError', 'TimeoutError: ' + err.message);
|
|
42
35
|
if (onTimeout) {
|
package/dist/string/json.util.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports._jsonParse = exports._jsonParseOrUndefined = exports._jsonParseIfPossible = void 0;
|
|
4
|
-
const
|
|
4
|
+
const error_util_1 = require("../error/error.util");
|
|
5
5
|
// const possibleJsonStartTokens = ['{', '[', '"']
|
|
6
6
|
const DETECT_JSON = /^\s*[{["\-\d]/;
|
|
7
7
|
/**
|
|
@@ -44,7 +44,7 @@ function _jsonParse(s, reviver) {
|
|
|
44
44
|
return JSON.parse(s, reviver);
|
|
45
45
|
}
|
|
46
46
|
catch {
|
|
47
|
-
throw new
|
|
47
|
+
throw new error_util_1.JsonParseError({
|
|
48
48
|
text: s,
|
|
49
49
|
});
|
|
50
50
|
}
|
package/dist-esm/error/assert.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { _deepEquals, _isErrorObject, _stringifyAny } from '..';
|
|
2
|
-
import { AppError } from './app.error';
|
|
1
|
+
import { _deepEquals, _isErrorObject, _stringifyAny, AssertionError } from '..';
|
|
3
2
|
/**
|
|
4
3
|
* Evaluates the `condition` (casts it to Boolean).
|
|
5
4
|
* Expects it to be truthy, otherwise throws AppError.
|
|
@@ -103,8 +102,3 @@ export function _assertTypeOf(v, expectedType, message) {
|
|
|
103
102
|
});
|
|
104
103
|
}
|
|
105
104
|
}
|
|
106
|
-
export class AssertionError extends AppError {
|
|
107
|
-
constructor(message, data) {
|
|
108
|
-
super(message, data, { name: 'AssertionError' });
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { _jsonParseIfPossible, _stringifyAny, _truncate, _truncateMiddle } from '..';
|
|
2
2
|
/**
|
|
3
3
|
* Useful to ensure that error in `catch (err) { ... }`
|
|
4
4
|
* is indeed an Error (and not e.g `string` or `undefined`).
|
|
@@ -207,3 +207,112 @@ export function _errorDataAppend(err, data) {
|
|
|
207
207
|
err.data = Object.assign(Object.assign({}, err.data), data);
|
|
208
208
|
return err;
|
|
209
209
|
}
|
|
210
|
+
/**
|
|
211
|
+
* Base class for all our (not system) errors.
|
|
212
|
+
*
|
|
213
|
+
* message - "technical" message. Frontend decides to show it or not.
|
|
214
|
+
* data - optional "any" payload.
|
|
215
|
+
* data.userFriendly - if present, will be displayed to the User as is.
|
|
216
|
+
*
|
|
217
|
+
* Based on: https://medium.com/@xpl/javascript-deriving-from-error-properly-8d2f8f315801
|
|
218
|
+
*/
|
|
219
|
+
export class AppError extends Error {
|
|
220
|
+
constructor(message, data = {}, opt = {}) {
|
|
221
|
+
super(message);
|
|
222
|
+
const { name = this.constructor.name, cause } = opt;
|
|
223
|
+
Object.defineProperties(this, {
|
|
224
|
+
name: {
|
|
225
|
+
value: name,
|
|
226
|
+
configurable: true,
|
|
227
|
+
writable: true,
|
|
228
|
+
},
|
|
229
|
+
data: {
|
|
230
|
+
value: data,
|
|
231
|
+
writable: true,
|
|
232
|
+
configurable: true,
|
|
233
|
+
enumerable: false,
|
|
234
|
+
},
|
|
235
|
+
});
|
|
236
|
+
if (cause) {
|
|
237
|
+
Object.defineProperty(this, 'cause', {
|
|
238
|
+
value: _anyToErrorObject(cause),
|
|
239
|
+
writable: true,
|
|
240
|
+
configurable: true,
|
|
241
|
+
enumerable: true, // unlike standard - setting it to true for "visibility"
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
// this is to allow changing this.constuctor.name to a non-minified version
|
|
245
|
+
Object.defineProperty(this.constructor, 'name', {
|
|
246
|
+
value: name,
|
|
247
|
+
configurable: true,
|
|
248
|
+
writable: true,
|
|
249
|
+
});
|
|
250
|
+
// todo: check if it's needed at all!
|
|
251
|
+
// if (Error.captureStackTrace) {
|
|
252
|
+
// Error.captureStackTrace(this, this.constructor)
|
|
253
|
+
// } else {
|
|
254
|
+
// Object.defineProperty(this, 'stack', {
|
|
255
|
+
// value: new Error().stack, // eslint-disable-line unicorn/error-message
|
|
256
|
+
// writable: true,
|
|
257
|
+
// configurable: true,
|
|
258
|
+
// })
|
|
259
|
+
// }
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Error that is thrown when Http Request was made and returned an error.
|
|
264
|
+
* Thrown by, for example, Fetcher.
|
|
265
|
+
*
|
|
266
|
+
* On the Frontend this Error class represents the error when calling the API,
|
|
267
|
+
* contains all the necessary request and response information.
|
|
268
|
+
*
|
|
269
|
+
* On the Backend, similarly, it represents the error when calling some 3rd-party API
|
|
270
|
+
* (backend-to-backend call).
|
|
271
|
+
* On the Backend it often propagates all the way to the Backend error handler,
|
|
272
|
+
* where it would be wrapped in BackendErrorResponseObject.
|
|
273
|
+
*
|
|
274
|
+
* Please note that `ErrorData.backendResponseStatusCode` is NOT exactly the same as
|
|
275
|
+
* `HttpRequestErrorData.responseStatusCode`.
|
|
276
|
+
* E.g 3rd-party call may return 401, but our Backend will still wrap it into an 500 error
|
|
277
|
+
* (by default).
|
|
278
|
+
*/
|
|
279
|
+
export class HttpRequestError extends AppError {
|
|
280
|
+
constructor(message, data, opt) {
|
|
281
|
+
if (data.response) {
|
|
282
|
+
Object.defineProperty(data, 'response', {
|
|
283
|
+
enumerable: false,
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
super(message, data, Object.assign(Object.assign({}, opt), { name: 'HttpRequestError' }));
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
export class AssertionError extends AppError {
|
|
290
|
+
constructor(message, data) {
|
|
291
|
+
super(message, data, { name: 'AssertionError' });
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
export class JsonParseError extends AppError {
|
|
295
|
+
constructor(data) {
|
|
296
|
+
const message = ['Failed to parse', data.text && _truncateMiddle(data.text, 200)]
|
|
297
|
+
.filter(Boolean)
|
|
298
|
+
.join(': ');
|
|
299
|
+
super(message, data, { name: 'JsonParseError' });
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
export class TimeoutError extends AppError {
|
|
303
|
+
constructor(message, data, opt) {
|
|
304
|
+
super(message, data, Object.assign(Object.assign({}, opt), { name: 'TimeoutError' }));
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* It is thrown when Error was expected, but didn't happen
|
|
309
|
+
* ("pass" happened instead).
|
|
310
|
+
* "Pass" means "no error".
|
|
311
|
+
*/
|
|
312
|
+
export class UnexpectedPassError extends AppError {
|
|
313
|
+
constructor() {
|
|
314
|
+
super('expected error was not thrown', {}, {
|
|
315
|
+
name: 'UnexpectedPassError',
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
}
|