@marianmeres/http-utils 1.12.0 → 1.14.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.d.ts CHANGED
@@ -89,5 +89,6 @@ export declare const HTTP_ERROR: {
89
89
  BadGateway: typeof BadGateway;
90
90
  ServiceUnavailable: typeof ServiceUnavailable;
91
91
  };
92
- export declare const createHttpError: (code: number | string, message?: string | null, body?: string | null, cause?: any) => BadRequest | Unauthorized | Forbidden | NotFound | MethodNotAllowed | RequestTimeout | Conflict | Gone | UnprocessableContent | ImATeapot | InternalServerError | NotImplemented | BadGateway | ServiceUnavailable;
92
+ export declare const createHttpError: (code: number | string, message?: string | null, body?: string | null, cause?: any) => HttpError;
93
+ export declare const getErrorMessage: (e: any, stripErrorPrefix?: boolean) => string;
93
94
  export {};
package/dist/index.cjs CHANGED
@@ -241,6 +241,15 @@ const _wellKnownCtorMap = {
241
241
  '502': BadGateway,
242
242
  '503': ServiceUnavailable,
243
243
  };
244
+ const _maybeJsonParse = (v) => {
245
+ if (typeof v === 'string') {
246
+ try {
247
+ v = JSON.parse(v);
248
+ }
249
+ catch (e) { }
250
+ }
251
+ return v;
252
+ };
244
253
  const createHttpError = (code, message,
245
254
  // arbitrary content, typically http response body which threw this error
246
255
  // (will be JSON.parse-d if the content is a valid json string)
@@ -252,22 +261,9 @@ cause) => {
252
261
  code = Number(code);
253
262
  if (isNaN(code) || !(code >= 400 && code < 600))
254
263
  code = fallback.CODE;
255
- // opinionated convention
256
- if (typeof body === 'string') {
257
- // prettier-ignore
258
- try {
259
- body = JSON.parse(body);
260
- }
261
- catch (e) { }
262
- }
263
- // opinionated convention
264
- if (typeof cause === 'string') {
265
- // prettier-ignore
266
- try {
267
- cause = JSON.parse(cause);
268
- }
269
- catch (e) { }
270
- }
264
+ // opinionated conventions
265
+ body = _maybeJsonParse(body);
266
+ cause = _maybeJsonParse(cause);
271
267
  // try to find the well known one, otherwise fallback to generic
272
268
  const ctor = _wellKnownCtorMap[`${code}`] ?? HttpError;
273
269
  //
@@ -280,6 +276,42 @@ cause) => {
280
276
  e.body = body;
281
277
  return e;
282
278
  };
279
+ const getErrorMessage = (e, stripErrorPrefix = true) => {
280
+ if (!e)
281
+ return '';
282
+ // PROBLEM is that error may bubble from various sources which are not always under control
283
+ // and even if they were it still may not be trivial to keep similar structure on each error boundary...
284
+ // So, we'll just do what we can, it will not be perfect, but should handle most cases most of the time.
285
+ // Also, I'm relying on some of my own opinionated conventions as well...
286
+ const cause = _maybeJsonParse(e?.cause);
287
+ const body = _maybeJsonParse(e?.body);
288
+ let msg =
289
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
290
+ // e.cause is the standard prop for error details, so should be considered as
291
+ // the most authoritative (if available)
292
+ // "code" and "message" are my own conventions
293
+ cause?.code ||
294
+ cause?.message ||
295
+ (typeof cause === 'string' ? cause : null) ||
296
+ // non-standard "body" is this package's HttpError prop
297
+ body?.error?.message ||
298
+ body?.message ||
299
+ (typeof body === 'string' ? body : null) ||
300
+ // the common message from Error ctor (e.g. "Foo" if new TypeError("Foo"))
301
+ e?.message ||
302
+ // the Error class name (e.g. TypeError)
303
+ e?.name ||
304
+ // this should handle (almost) everything else (mainly if e is not an Error instance)
305
+ e?.toString() ||
306
+ // very last fallback if `toString()` was not available (or returned empty)
307
+ 'Unknown Error';
308
+ // cast to string
309
+ msg = `${msg}`;
310
+ if (stripErrorPrefix) {
311
+ msg = msg.replace(/^[^:]*Error: /, '');
312
+ }
313
+ return msg;
314
+ };
283
315
 
284
316
  const _fetchRaw = async ({ method, path, data = null, token = null, headers = null, signal = null, credentials, }) => {
285
317
  headers = Object.entries(headers || {}).reduce((m, [k, v]) => ({ ...m, [k.toLowerCase()]: v }), {});
@@ -405,3 +437,4 @@ exports.HTTP_ERROR = HTTP_ERROR;
405
437
  exports.HTTP_STATUS = HTTP_STATUS;
406
438
  exports.createHttpApi = createHttpApi;
407
439
  exports.createHttpError = createHttpError;
440
+ exports.getErrorMessage = getErrorMessage;
package/dist/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  export { HTTP_STATUS } from './status.js';
2
- export { HTTP_ERROR, createHttpError } from './error.js';
2
+ export { HTTP_ERROR, createHttpError, getErrorMessage } from './error.js';
3
3
  export { createHttpApi } from './api.js';
package/dist/index.js CHANGED
@@ -239,6 +239,15 @@ const _wellKnownCtorMap = {
239
239
  '502': BadGateway,
240
240
  '503': ServiceUnavailable,
241
241
  };
242
+ const _maybeJsonParse = (v) => {
243
+ if (typeof v === 'string') {
244
+ try {
245
+ v = JSON.parse(v);
246
+ }
247
+ catch (e) { }
248
+ }
249
+ return v;
250
+ };
242
251
  const createHttpError = (code, message,
243
252
  // arbitrary content, typically http response body which threw this error
244
253
  // (will be JSON.parse-d if the content is a valid json string)
@@ -250,22 +259,9 @@ cause) => {
250
259
  code = Number(code);
251
260
  if (isNaN(code) || !(code >= 400 && code < 600))
252
261
  code = fallback.CODE;
253
- // opinionated convention
254
- if (typeof body === 'string') {
255
- // prettier-ignore
256
- try {
257
- body = JSON.parse(body);
258
- }
259
- catch (e) { }
260
- }
261
- // opinionated convention
262
- if (typeof cause === 'string') {
263
- // prettier-ignore
264
- try {
265
- cause = JSON.parse(cause);
266
- }
267
- catch (e) { }
268
- }
262
+ // opinionated conventions
263
+ body = _maybeJsonParse(body);
264
+ cause = _maybeJsonParse(cause);
269
265
  // try to find the well known one, otherwise fallback to generic
270
266
  const ctor = _wellKnownCtorMap[`${code}`] ?? HttpError;
271
267
  //
@@ -278,6 +274,42 @@ cause) => {
278
274
  e.body = body;
279
275
  return e;
280
276
  };
277
+ const getErrorMessage = (e, stripErrorPrefix = true) => {
278
+ if (!e)
279
+ return '';
280
+ // PROBLEM is that error may bubble from various sources which are not always under control
281
+ // and even if they were it still may not be trivial to keep similar structure on each error boundary...
282
+ // So, we'll just do what we can, it will not be perfect, but should handle most cases most of the time.
283
+ // Also, I'm relying on some of my own opinionated conventions as well...
284
+ const cause = _maybeJsonParse(e?.cause);
285
+ const body = _maybeJsonParse(e?.body);
286
+ let msg =
287
+ // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error/cause
288
+ // e.cause is the standard prop for error details, so should be considered as
289
+ // the most authoritative (if available)
290
+ // "code" and "message" are my own conventions
291
+ cause?.code ||
292
+ cause?.message ||
293
+ (typeof cause === 'string' ? cause : null) ||
294
+ // non-standard "body" is this package's HttpError prop
295
+ body?.error?.message ||
296
+ body?.message ||
297
+ (typeof body === 'string' ? body : null) ||
298
+ // the common message from Error ctor (e.g. "Foo" if new TypeError("Foo"))
299
+ e?.message ||
300
+ // the Error class name (e.g. TypeError)
301
+ e?.name ||
302
+ // this should handle (almost) everything else (mainly if e is not an Error instance)
303
+ e?.toString() ||
304
+ // very last fallback if `toString()` was not available (or returned empty)
305
+ 'Unknown Error';
306
+ // cast to string
307
+ msg = `${msg}`;
308
+ if (stripErrorPrefix) {
309
+ msg = msg.replace(/^[^:]*Error: /, '');
310
+ }
311
+ return msg;
312
+ };
281
313
 
282
314
  const _fetchRaw = async ({ method, path, data = null, token = null, headers = null, signal = null, credentials, }) => {
283
315
  headers = Object.entries(headers || {}).reduce((m, [k, v]) => ({ ...m, [k.toLowerCase()]: v }), {});
@@ -399,4 +431,4 @@ function createHttpApi(base, defaults, factoryErrorMessageExtractor) {
399
431
  }
400
432
  createHttpApi.defaultErrorMessageExtractor = null;
401
433
 
402
- export { HTTP_ERROR, HTTP_STATUS, createHttpApi, createHttpError };
434
+ export { HTTP_ERROR, HTTP_STATUS, createHttpApi, createHttpError, getErrorMessage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/http-utils",
3
- "version": "1.12.0",
3
+ "version": "1.14.0",
4
4
  "description": "Misc DRY http fetch related helpers",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",