@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.
Files changed (40) hide show
  1. package/dist/error/assert.d.ts +0 -4
  2. package/dist/error/assert.js +7 -14
  3. package/dist/error/error.util.d.ts +80 -1
  4. package/dist/error/error.util.js +117 -2
  5. package/dist/error/try.d.ts +0 -9
  6. package/dist/error/try.js +6 -19
  7. package/dist/http/fetcher.d.ts +1 -1
  8. package/dist/http/fetcher.js +3 -4
  9. package/dist/index.d.ts +0 -3
  10. package/dist/index.js +0 -3
  11. package/dist/promise/pTimeout.d.ts +1 -4
  12. package/dist/promise/pTimeout.js +2 -9
  13. package/dist/string/json.util.js +2 -2
  14. package/dist-esm/error/assert.js +1 -7
  15. package/dist-esm/error/error.util.js +110 -1
  16. package/dist-esm/error/try.js +1 -13
  17. package/dist-esm/http/fetcher.js +2 -3
  18. package/dist-esm/index.js +0 -3
  19. package/dist-esm/promise/pTimeout.js +1 -7
  20. package/dist-esm/string/json.util.js +1 -1
  21. package/package.json +1 -1
  22. package/src/error/assert.ts +1 -8
  23. package/src/error/error.util.ts +163 -1
  24. package/src/error/try.ts +1 -18
  25. package/src/http/fetcher.ts +8 -3
  26. package/src/index.ts +0 -3
  27. package/src/promise/pTimeout.ts +1 -8
  28. package/src/string/json.util.ts +1 -1
  29. package/dist/error/app.error.d.ts +0 -31
  30. package/dist/error/app.error.js +0 -57
  31. package/dist/error/httpRequestError.d.ts +0 -28
  32. package/dist/error/httpRequestError.js +0 -32
  33. package/dist/error/jsonParseError.d.ts +0 -11
  34. package/dist/error/jsonParseError.js +0 -14
  35. package/dist-esm/error/app.error.js +0 -53
  36. package/dist-esm/error/httpRequestError.js +0 -28
  37. package/dist-esm/error/jsonParseError.js +0 -10
  38. package/src/error/app.error.ts +0 -81
  39. package/src/error/httpRequestError.ts +0 -38
  40. package/src/error/jsonParseError.ts +0 -20
@@ -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
- }
@@ -1,8 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.AssertionError = exports._assertTypeOf = exports._assertIsNumber = exports._assertIsString = exports._assertIsErrorObject = exports._assertErrorClassOrRethrow = exports._assertIsError = exports._assertDeepEquals = exports._assertEquals = exports._assert = void 0;
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
+ }
@@ -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 __1.AppError)) {
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;
@@ -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.UnexpectedPassError = exports.pTry = exports._try = void 0;
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`);
@@ -1,6 +1,6 @@
1
1
  /// <reference lib="dom" />
2
2
  /// <reference lib="dom.iterable" />
3
- import { HttpRequestError } from '../error/httpRequestError';
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
  /**
@@ -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, httpRequestError_1.HttpRequestError);
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 pTimeout_1.TimeoutError(`request timed out after ${timeoutSeconds} sec`));
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 httpRequestError_1.HttpRequestError(message, (0, object_util_1._filterNullishValues)({
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.
@@ -1,14 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.pTimeout = exports.pTimeoutFn = exports.TimeoutError = void 0;
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) {
@@ -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 jsonParseError_1 = require("../error/jsonParseError");
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 jsonParseError_1.JsonParseError({
47
+ throw new error_util_1.JsonParseError({
48
48
  text: s,
49
49
  });
50
50
  }
@@ -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 { AppError, _jsonParseIfPossible, _stringifyAny, _truncate } from '..';
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
+ }