@twinedo/app-error 1.0.2 → 1.0.3

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/README.md CHANGED
@@ -168,3 +168,35 @@ if (result.ok) {
168
168
  console.error(result.error.message);
169
169
  }
170
170
  ```
171
+
172
+ ## FAQ
173
+ ### 1. Why not just use `try/catch` with `err.message`?
174
+ Because real-world errors are inconsistent:
175
+ - fetch doesn’t throw on 4xx/5xx (you must check res.ok)
176
+ - axios errors have a different shape (error.response, error.request)
177
+ - network/timeout/runtime errors look different across environments
178
+ This library normalizes them into one predictable AppError.
179
+
180
+ ### 2. Does `message` always contain the backend error message?
181
+ When possible, yes. Otherwise it falls back to a safe default.<br />
182
+ `message` is always a non-empty string. If the backend returns no usable message (e.g. `{}`, `null`), it becomes `"Something went wrong"`.
183
+
184
+ ### 3. What about status?
185
+ `status` is set only when there is an actual HTTP response (kind "http"), e.g. `400`, `404`, `500`.<br />
186
+ For network/timeout/runtime `errors`, `status` is `undefined`.
187
+
188
+ ### 4. Do I need to define a policy?
189
+ Only if your backend error shape is custom and you want more accurate extraction for:
190
+ - `message`
191
+ - `code`
192
+ - `requestId`<br />
193
+ If your backend already returns `{ message: "..." }`, you can usually skip policies.
194
+
195
+ ### 5. Is it framework-agnostic?
196
+ Yes. It’s plain JS/TS and can be used in React, React Native, Vue, Svelte, Angular, Node, etc.
197
+
198
+ ### 6. Does it add a lot to bundle size?
199
+ It’s dependency-free and tree-shakable in modern bundlers. Your app typically includes only what you import.
200
+
201
+ ### 7. Is this a replacement for an HTTP client?
202
+ No. This library does not send requests or manage retries. It only normalizes errors.
package/dist/index.cjs CHANGED
@@ -156,11 +156,30 @@ var defaultHttpRetryable = (status) => {
156
156
  if (typeof status !== "number") return false;
157
157
  return status >= 500 && status <= 599;
158
158
  };
159
+ var DEFAULT_HTTP_SUGGESTIONS = {
160
+ 400: "Please review your request and ensure all fields are correct.",
161
+ 401: "Please ensure you have valid credentials and try again.",
162
+ 403: "You do not have permission to perform this action.",
163
+ 404: "The requested resource could not be found. Please verify your request.",
164
+ 408: "The request took too long. Please try again shortly.",
165
+ 409: "A conflict occurred. Please refresh and try again.",
166
+ 422: "Some of the provided data is invalid. Please review your input.",
167
+ 429: "Too many requests. Please wait a moment and try again.",
168
+ 500: "An internal server error occurred. Please try again later or contact support.",
169
+ 502: "The server received an invalid response. Please try again later.",
170
+ 503: "The service is temporarily unavailable. Please try again later.",
171
+ 504: "The server did not respond in time. Please try again later."
172
+ };
173
+ var defaultHttpSuggestion = (status) => {
174
+ if (typeof status !== "number") return void 0;
175
+ return DEFAULT_HTTP_SUGGESTIONS[status];
176
+ };
159
177
  var DEFAULT_HTTP_POLICY = {
160
178
  message: defaultHttpMessage,
161
179
  code: defaultHttpCode,
162
180
  requestId: defaultRequestId,
163
- retryable: defaultHttpRetryable
181
+ retryable: defaultHttpRetryable,
182
+ suggestion: defaultHttpSuggestion
164
183
  };
165
184
  var defineErrorPolicy = (...configs) => {
166
185
  const merged = {};
@@ -173,7 +192,8 @@ var defineErrorPolicy = (...configs) => {
173
192
  message: merged.message ?? DEFAULT_HTTP_POLICY.message,
174
193
  code: merged.code ?? DEFAULT_HTTP_POLICY.code,
175
194
  requestId: merged.requestId ?? DEFAULT_HTTP_POLICY.requestId,
176
- retryable: merged.retryable ?? DEFAULT_HTTP_POLICY.retryable
195
+ retryable: merged.retryable ?? DEFAULT_HTTP_POLICY.retryable,
196
+ suggestion: merged.suggestion ?? DEFAULT_HTTP_POLICY.suggestion
177
197
  }
178
198
  };
179
199
  };
@@ -192,7 +212,9 @@ var isAppError = (value) => {
192
212
  if (!isRecord2(value)) return false;
193
213
  const kind = value.kind;
194
214
  if (typeof kind !== "string" || !(kind in APP_ERROR_KINDS)) return false;
195
- return typeof value.message === "string";
215
+ if (typeof value.message !== "string") return false;
216
+ if (typeof value.suggestion !== "string") return false;
217
+ return true;
196
218
  };
197
219
 
198
220
  // src/fromFetch.ts
@@ -216,20 +238,30 @@ var safeInvoke = (fn) => {
216
238
  var fromFetch = (response, body, policy) => {
217
239
  const resolvedPolicy = defineErrorPolicy(policy);
218
240
  const status = typeof response.status === "number" ? response.status : void 0;
241
+ const httpResponse = {
242
+ ...status !== void 0 ? { status } : {},
243
+ ...response.statusText ? { statusText: response.statusText } : {},
244
+ ...response.headers !== void 0 ? { headers: response.headers } : {}
245
+ };
219
246
  const message = normalizeMessage(
220
- safeInvoke(() => resolvedPolicy.http.message(body, response))
247
+ safeInvoke(() => resolvedPolicy.http.message(body, httpResponse))
221
248
  ) ?? DEFAULT_MESSAGE;
222
249
  const code = normalizeMessage(
223
- safeInvoke(() => resolvedPolicy.http.code(body, response))
250
+ safeInvoke(() => resolvedPolicy.http.code(body, httpResponse))
224
251
  );
225
252
  const requestId = normalizeMessage(
226
253
  safeInvoke(() => resolvedPolicy.http.requestId(response.headers))
227
254
  );
228
255
  const retryable = safeInvoke(() => resolvedPolicy.http.retryable(status)) ?? defaultRetryable(status);
256
+ const DEFAULT_SUGGESTION = "An unexpected error occurred. Please try again or contact support.";
257
+ const suggestion = normalizeMessage(
258
+ safeInvoke(() => resolvedPolicy.http.suggestion(status, body, httpResponse))
259
+ ) ?? DEFAULT_SUGGESTION;
229
260
  return {
230
261
  kind: "http",
231
262
  message,
232
263
  retryable,
264
+ suggestion,
233
265
  ...status !== void 0 ? { status } : {},
234
266
  ...code ? { code } : {},
235
267
  ...requestId ? { requestId } : {},
@@ -332,6 +364,14 @@ var toHttpResponseLike = (info) => {
332
364
 
333
365
  // src/toAppError.ts
334
366
  var DEFAULT_MESSAGE2 = "Something went wrong";
367
+ var DEFAULT_KIND_SUGGESTIONS = {
368
+ network: "Please check your internet connection and try again.",
369
+ timeout: "The request took too long. Please try again shortly.",
370
+ parse: "The server returned an unexpected response. Please try again or contact support.",
371
+ validation: "Please review your input and correct any errors.",
372
+ unknown: "An unexpected error occurred. Please try again or contact support.",
373
+ http: ""
374
+ };
335
375
  var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
336
376
  "ENOTFOUND",
337
377
  "ECONNREFUSED",
@@ -401,16 +441,19 @@ var isValidationError = (error, name) => {
401
441
  var normalizeExisting = (error) => {
402
442
  const message = normalizeMessage2(error.message) ?? DEFAULT_MESSAGE2;
403
443
  const retryable = typeof error.retryable === "boolean" ? error.retryable : defaultRetryable2(error.kind, error.status);
444
+ const suggestion = normalizeMessage2(error.suggestion) ?? (DEFAULT_KIND_SUGGESTIONS[error.kind] || "An unexpected error occurred. Please try again or contact support.");
404
445
  return {
405
446
  ...error,
406
447
  message,
407
- retryable
448
+ retryable,
449
+ suggestion
408
450
  };
409
451
  };
410
452
  var buildAppError = (options) => ({
411
453
  kind: options.kind,
412
454
  message: options.message,
413
455
  retryable: options.retryable,
456
+ suggestion: options.suggestion,
414
457
  ...options.status !== void 0 ? { status: options.status } : {},
415
458
  ...options.code ? { code: options.code } : {},
416
459
  ...options.requestId ? { requestId: options.requestId } : {},
@@ -433,9 +476,13 @@ var fromStatusObject = (error, policy) => {
433
476
  const code = safeInvoke2(() => policy.http.code(details, response));
434
477
  const requestId = safeInvoke2(() => policy.http.requestId(response.headers));
435
478
  const retryable = safeInvoke2(() => policy.http.retryable(status)) ?? defaultRetryable2("http", status);
479
+ const suggestion = normalizeMessage2(
480
+ safeInvoke2(() => policy.http.suggestion(status, details, response))
481
+ ) ?? DEFAULT_KIND_SUGGESTIONS.unknown;
436
482
  return buildAppError({
437
483
  kind: "http",
438
484
  message,
485
+ suggestion,
439
486
  status,
440
487
  code: normalizeMessage2(code),
441
488
  retryable,
@@ -462,9 +509,13 @@ var toAppError = (error, policy) => {
462
509
  () => resolvedPolicy.http.requestId(axiosInfo.headers)
463
510
  );
464
511
  const retryable = safeInvoke2(() => resolvedPolicy.http.retryable(axiosInfo.status)) ?? defaultRetryable2("http", axiosInfo.status);
512
+ const suggestion = normalizeMessage2(
513
+ safeInvoke2(() => resolvedPolicy.http.suggestion(axiosInfo.status, axiosInfo.data, response))
514
+ ) ?? DEFAULT_KIND_SUGGESTIONS.unknown;
465
515
  return buildAppError({
466
516
  kind: "http",
467
517
  message: message2,
518
+ suggestion,
468
519
  status: axiosInfo.status,
469
520
  code: normalizeMessage2(code2),
470
521
  retryable,
@@ -477,6 +528,7 @@ var toAppError = (error, policy) => {
477
528
  return buildAppError({
478
529
  kind: "timeout",
479
530
  message: DEFAULT_MESSAGE2,
531
+ suggestion: DEFAULT_KIND_SUGGESTIONS.timeout,
480
532
  retryable: false,
481
533
  cause: error
482
534
  });
@@ -485,6 +537,7 @@ var toAppError = (error, policy) => {
485
537
  return buildAppError({
486
538
  kind: "network",
487
539
  message: DEFAULT_MESSAGE2,
540
+ suggestion: DEFAULT_KIND_SUGGESTIONS.network,
488
541
  retryable: true,
489
542
  cause: error
490
543
  });
@@ -495,6 +548,7 @@ var toAppError = (error, policy) => {
495
548
  return buildAppError({
496
549
  kind: "timeout",
497
550
  message: DEFAULT_MESSAGE2,
551
+ suggestion: DEFAULT_KIND_SUGGESTIONS.timeout,
498
552
  retryable: false,
499
553
  cause: error
500
554
  });
@@ -503,6 +557,7 @@ var toAppError = (error, policy) => {
503
557
  return buildAppError({
504
558
  kind: "network",
505
559
  message: DEFAULT_MESSAGE2,
560
+ suggestion: DEFAULT_KIND_SUGGESTIONS.network,
506
561
  retryable: true,
507
562
  cause: error
508
563
  });
@@ -511,6 +566,7 @@ var toAppError = (error, policy) => {
511
566
  return buildAppError({
512
567
  kind: "parse",
513
568
  message: DEFAULT_MESSAGE2,
569
+ suggestion: DEFAULT_KIND_SUGGESTIONS.parse,
514
570
  retryable: false,
515
571
  cause: error
516
572
  });
@@ -519,6 +575,7 @@ var toAppError = (error, policy) => {
519
575
  return buildAppError({
520
576
  kind: "validation",
521
577
  message: DEFAULT_MESSAGE2,
578
+ suggestion: DEFAULT_KIND_SUGGESTIONS.validation,
522
579
  retryable: false,
523
580
  cause: error,
524
581
  details: error
@@ -531,6 +588,7 @@ var toAppError = (error, policy) => {
531
588
  return buildAppError({
532
589
  kind: "unknown",
533
590
  message: DEFAULT_MESSAGE2,
591
+ suggestion: DEFAULT_KIND_SUGGESTIONS.unknown,
534
592
  retryable: false,
535
593
  cause: error
536
594
  });
package/dist/index.d.cts CHANGED
@@ -2,6 +2,7 @@ type AppErrorKind = "http" | "network" | "timeout" | "parse" | "validation" | "u
2
2
  type AppError = {
3
3
  kind: AppErrorKind;
4
4
  message: string;
5
+ suggestion: string;
5
6
  status?: number;
6
7
  code?: string;
7
8
  retryable?: boolean;
@@ -24,6 +25,7 @@ type HttpPolicy = {
24
25
  code: (data: unknown, response?: HttpResponseLike) => string | undefined;
25
26
  requestId: (headers?: HeadersLike) => string | undefined;
26
27
  retryable: (status?: number) => boolean;
28
+ suggestion: (status?: number, data?: unknown, response?: HttpResponseLike) => string | undefined;
27
29
  };
28
30
  type ErrorPolicy = {
29
31
  http?: Partial<HttpPolicy>;
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ type AppErrorKind = "http" | "network" | "timeout" | "parse" | "validation" | "u
2
2
  type AppError = {
3
3
  kind: AppErrorKind;
4
4
  message: string;
5
+ suggestion: string;
5
6
  status?: number;
6
7
  code?: string;
7
8
  retryable?: boolean;
@@ -24,6 +25,7 @@ type HttpPolicy = {
24
25
  code: (data: unknown, response?: HttpResponseLike) => string | undefined;
25
26
  requestId: (headers?: HeadersLike) => string | undefined;
26
27
  retryable: (status?: number) => boolean;
28
+ suggestion: (status?: number, data?: unknown, response?: HttpResponseLike) => string | undefined;
27
29
  };
28
30
  type ErrorPolicy = {
29
31
  http?: Partial<HttpPolicy>;
package/dist/index.js CHANGED
@@ -123,11 +123,30 @@ var defaultHttpRetryable = (status) => {
123
123
  if (typeof status !== "number") return false;
124
124
  return status >= 500 && status <= 599;
125
125
  };
126
+ var DEFAULT_HTTP_SUGGESTIONS = {
127
+ 400: "Please review your request and ensure all fields are correct.",
128
+ 401: "Please ensure you have valid credentials and try again.",
129
+ 403: "You do not have permission to perform this action.",
130
+ 404: "The requested resource could not be found. Please verify your request.",
131
+ 408: "The request took too long. Please try again shortly.",
132
+ 409: "A conflict occurred. Please refresh and try again.",
133
+ 422: "Some of the provided data is invalid. Please review your input.",
134
+ 429: "Too many requests. Please wait a moment and try again.",
135
+ 500: "An internal server error occurred. Please try again later or contact support.",
136
+ 502: "The server received an invalid response. Please try again later.",
137
+ 503: "The service is temporarily unavailable. Please try again later.",
138
+ 504: "The server did not respond in time. Please try again later."
139
+ };
140
+ var defaultHttpSuggestion = (status) => {
141
+ if (typeof status !== "number") return void 0;
142
+ return DEFAULT_HTTP_SUGGESTIONS[status];
143
+ };
126
144
  var DEFAULT_HTTP_POLICY = {
127
145
  message: defaultHttpMessage,
128
146
  code: defaultHttpCode,
129
147
  requestId: defaultRequestId,
130
- retryable: defaultHttpRetryable
148
+ retryable: defaultHttpRetryable,
149
+ suggestion: defaultHttpSuggestion
131
150
  };
132
151
  var defineErrorPolicy = (...configs) => {
133
152
  const merged = {};
@@ -140,7 +159,8 @@ var defineErrorPolicy = (...configs) => {
140
159
  message: merged.message ?? DEFAULT_HTTP_POLICY.message,
141
160
  code: merged.code ?? DEFAULT_HTTP_POLICY.code,
142
161
  requestId: merged.requestId ?? DEFAULT_HTTP_POLICY.requestId,
143
- retryable: merged.retryable ?? DEFAULT_HTTP_POLICY.retryable
162
+ retryable: merged.retryable ?? DEFAULT_HTTP_POLICY.retryable,
163
+ suggestion: merged.suggestion ?? DEFAULT_HTTP_POLICY.suggestion
144
164
  }
145
165
  };
146
166
  };
@@ -159,7 +179,9 @@ var isAppError = (value) => {
159
179
  if (!isRecord2(value)) return false;
160
180
  const kind = value.kind;
161
181
  if (typeof kind !== "string" || !(kind in APP_ERROR_KINDS)) return false;
162
- return typeof value.message === "string";
182
+ if (typeof value.message !== "string") return false;
183
+ if (typeof value.suggestion !== "string") return false;
184
+ return true;
163
185
  };
164
186
 
165
187
  // src/fromFetch.ts
@@ -183,20 +205,30 @@ var safeInvoke = (fn) => {
183
205
  var fromFetch = (response, body, policy) => {
184
206
  const resolvedPolicy = defineErrorPolicy(policy);
185
207
  const status = typeof response.status === "number" ? response.status : void 0;
208
+ const httpResponse = {
209
+ ...status !== void 0 ? { status } : {},
210
+ ...response.statusText ? { statusText: response.statusText } : {},
211
+ ...response.headers !== void 0 ? { headers: response.headers } : {}
212
+ };
186
213
  const message = normalizeMessage(
187
- safeInvoke(() => resolvedPolicy.http.message(body, response))
214
+ safeInvoke(() => resolvedPolicy.http.message(body, httpResponse))
188
215
  ) ?? DEFAULT_MESSAGE;
189
216
  const code = normalizeMessage(
190
- safeInvoke(() => resolvedPolicy.http.code(body, response))
217
+ safeInvoke(() => resolvedPolicy.http.code(body, httpResponse))
191
218
  );
192
219
  const requestId = normalizeMessage(
193
220
  safeInvoke(() => resolvedPolicy.http.requestId(response.headers))
194
221
  );
195
222
  const retryable = safeInvoke(() => resolvedPolicy.http.retryable(status)) ?? defaultRetryable(status);
223
+ const DEFAULT_SUGGESTION = "An unexpected error occurred. Please try again or contact support.";
224
+ const suggestion = normalizeMessage(
225
+ safeInvoke(() => resolvedPolicy.http.suggestion(status, body, httpResponse))
226
+ ) ?? DEFAULT_SUGGESTION;
196
227
  return {
197
228
  kind: "http",
198
229
  message,
199
230
  retryable,
231
+ suggestion,
200
232
  ...status !== void 0 ? { status } : {},
201
233
  ...code ? { code } : {},
202
234
  ...requestId ? { requestId } : {},
@@ -299,6 +331,14 @@ var toHttpResponseLike = (info) => {
299
331
 
300
332
  // src/toAppError.ts
301
333
  var DEFAULT_MESSAGE2 = "Something went wrong";
334
+ var DEFAULT_KIND_SUGGESTIONS = {
335
+ network: "Please check your internet connection and try again.",
336
+ timeout: "The request took too long. Please try again shortly.",
337
+ parse: "The server returned an unexpected response. Please try again or contact support.",
338
+ validation: "Please review your input and correct any errors.",
339
+ unknown: "An unexpected error occurred. Please try again or contact support.",
340
+ http: ""
341
+ };
302
342
  var NETWORK_ERROR_CODES = /* @__PURE__ */ new Set([
303
343
  "ENOTFOUND",
304
344
  "ECONNREFUSED",
@@ -368,16 +408,19 @@ var isValidationError = (error, name) => {
368
408
  var normalizeExisting = (error) => {
369
409
  const message = normalizeMessage2(error.message) ?? DEFAULT_MESSAGE2;
370
410
  const retryable = typeof error.retryable === "boolean" ? error.retryable : defaultRetryable2(error.kind, error.status);
411
+ const suggestion = normalizeMessage2(error.suggestion) ?? (DEFAULT_KIND_SUGGESTIONS[error.kind] || "An unexpected error occurred. Please try again or contact support.");
371
412
  return {
372
413
  ...error,
373
414
  message,
374
- retryable
415
+ retryable,
416
+ suggestion
375
417
  };
376
418
  };
377
419
  var buildAppError = (options) => ({
378
420
  kind: options.kind,
379
421
  message: options.message,
380
422
  retryable: options.retryable,
423
+ suggestion: options.suggestion,
381
424
  ...options.status !== void 0 ? { status: options.status } : {},
382
425
  ...options.code ? { code: options.code } : {},
383
426
  ...options.requestId ? { requestId: options.requestId } : {},
@@ -400,9 +443,13 @@ var fromStatusObject = (error, policy) => {
400
443
  const code = safeInvoke2(() => policy.http.code(details, response));
401
444
  const requestId = safeInvoke2(() => policy.http.requestId(response.headers));
402
445
  const retryable = safeInvoke2(() => policy.http.retryable(status)) ?? defaultRetryable2("http", status);
446
+ const suggestion = normalizeMessage2(
447
+ safeInvoke2(() => policy.http.suggestion(status, details, response))
448
+ ) ?? DEFAULT_KIND_SUGGESTIONS.unknown;
403
449
  return buildAppError({
404
450
  kind: "http",
405
451
  message,
452
+ suggestion,
406
453
  status,
407
454
  code: normalizeMessage2(code),
408
455
  retryable,
@@ -429,9 +476,13 @@ var toAppError = (error, policy) => {
429
476
  () => resolvedPolicy.http.requestId(axiosInfo.headers)
430
477
  );
431
478
  const retryable = safeInvoke2(() => resolvedPolicy.http.retryable(axiosInfo.status)) ?? defaultRetryable2("http", axiosInfo.status);
479
+ const suggestion = normalizeMessage2(
480
+ safeInvoke2(() => resolvedPolicy.http.suggestion(axiosInfo.status, axiosInfo.data, response))
481
+ ) ?? DEFAULT_KIND_SUGGESTIONS.unknown;
432
482
  return buildAppError({
433
483
  kind: "http",
434
484
  message: message2,
485
+ suggestion,
435
486
  status: axiosInfo.status,
436
487
  code: normalizeMessage2(code2),
437
488
  retryable,
@@ -444,6 +495,7 @@ var toAppError = (error, policy) => {
444
495
  return buildAppError({
445
496
  kind: "timeout",
446
497
  message: DEFAULT_MESSAGE2,
498
+ suggestion: DEFAULT_KIND_SUGGESTIONS.timeout,
447
499
  retryable: false,
448
500
  cause: error
449
501
  });
@@ -452,6 +504,7 @@ var toAppError = (error, policy) => {
452
504
  return buildAppError({
453
505
  kind: "network",
454
506
  message: DEFAULT_MESSAGE2,
507
+ suggestion: DEFAULT_KIND_SUGGESTIONS.network,
455
508
  retryable: true,
456
509
  cause: error
457
510
  });
@@ -462,6 +515,7 @@ var toAppError = (error, policy) => {
462
515
  return buildAppError({
463
516
  kind: "timeout",
464
517
  message: DEFAULT_MESSAGE2,
518
+ suggestion: DEFAULT_KIND_SUGGESTIONS.timeout,
465
519
  retryable: false,
466
520
  cause: error
467
521
  });
@@ -470,6 +524,7 @@ var toAppError = (error, policy) => {
470
524
  return buildAppError({
471
525
  kind: "network",
472
526
  message: DEFAULT_MESSAGE2,
527
+ suggestion: DEFAULT_KIND_SUGGESTIONS.network,
473
528
  retryable: true,
474
529
  cause: error
475
530
  });
@@ -478,6 +533,7 @@ var toAppError = (error, policy) => {
478
533
  return buildAppError({
479
534
  kind: "parse",
480
535
  message: DEFAULT_MESSAGE2,
536
+ suggestion: DEFAULT_KIND_SUGGESTIONS.parse,
481
537
  retryable: false,
482
538
  cause: error
483
539
  });
@@ -486,6 +542,7 @@ var toAppError = (error, policy) => {
486
542
  return buildAppError({
487
543
  kind: "validation",
488
544
  message: DEFAULT_MESSAGE2,
545
+ suggestion: DEFAULT_KIND_SUGGESTIONS.validation,
489
546
  retryable: false,
490
547
  cause: error,
491
548
  details: error
@@ -498,6 +555,7 @@ var toAppError = (error, policy) => {
498
555
  return buildAppError({
499
556
  kind: "unknown",
500
557
  message: DEFAULT_MESSAGE2,
558
+ suggestion: DEFAULT_KIND_SUGGESTIONS.unknown,
501
559
  retryable: false,
502
560
  cause: error
503
561
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@twinedo/app-error",
3
- "version": "1.0.2",
3
+ "version": "1.0.3",
4
4
  "description": "A configurable error normalization layer for fetch, axios-like, and runtime errors.",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -40,4 +40,4 @@
40
40
  "url": "https://github.com/twinedo/app-error/issues"
41
41
  },
42
42
  "homepage": "https://github.com/twinedo/app-error#readme"
43
- }
43
+ }