@marianmeres/http-utils 2.9.0 → 2.10.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/AGENTS.md +2 -1
- package/API.md +4 -2
- package/README.md +2 -2
- package/dist/api.d.ts +10 -2
- package/dist/api.js +15 -8
- package/package.json +1 -1
package/AGENTS.md
CHANGED
|
@@ -162,7 +162,8 @@ function getErrorMessage(e: unknown, stripErrorPrefix?: boolean): string;
|
|
|
162
162
|
// AbortError/TimeoutError pass through untouched. Used internally by HttpApi.
|
|
163
163
|
// 3rd arg is a label string OR FetchOrThrowOptions { what?, onRequest?, onError? } (pure observers; a string normalizes to { what }).
|
|
164
164
|
// onRequest fires before dispatch (throw => request not sent). onError fires on every failure
|
|
165
|
-
// with kind: "abort"
|
|
165
|
+
// with { error, url, what?, kind: "abort"|"timeout"|"network", reason } (reason via getErrorMessage;
|
|
166
|
+
// throw => swallowed, real error preserved).
|
|
166
167
|
// Global defaults (overridable per call; resolution: per-call ?? global; instruments HttpApi too):
|
|
167
168
|
// fetchOrThrow.global.onRequest / fetchOrThrow.global.onError
|
|
168
169
|
function fetchOrThrow(
|
package/API.md
CHANGED
|
@@ -746,6 +746,8 @@ interface FetchOrThrowOptions {
|
|
|
746
746
|
url: string;
|
|
747
747
|
what?: string;
|
|
748
748
|
kind: "abort" | "timeout" | "network";
|
|
749
|
+
/** Human-readable reason (via `getErrorMessage`); always a string. */
|
|
750
|
+
reason: string;
|
|
749
751
|
}) => void;
|
|
750
752
|
}
|
|
751
753
|
|
|
@@ -773,8 +775,8 @@ Set defaults once on `fetchOrThrow.global`; per-call options win (resolution is
|
|
|
773
775
|
```ts
|
|
774
776
|
// app-wide defaults (also fire for every HttpApi request)
|
|
775
777
|
fetchOrThrow.global.onRequest = ({ method, url }) => console.debug(`→ ${method} ${url}`);
|
|
776
|
-
fetchOrThrow.global.onError = ({ url, kind }) =>
|
|
777
|
-
kind !== "abort" && console.error(`✗ ${url}`);
|
|
778
|
+
fetchOrThrow.global.onError = ({ url, kind, reason }) =>
|
|
779
|
+
kind !== "abort" && console.error(`✗ ${url}: ${reason}`);
|
|
778
780
|
|
|
779
781
|
// per-call object form (overrides the global onRequest for this call only)
|
|
780
782
|
await fetchOrThrow(url, init, { what: "Token issuer", onRequest: () => {} });
|
package/README.md
CHANGED
|
@@ -240,8 +240,8 @@ where neither a response nor an error ever arrives. Set defaults once on
|
|
|
240
240
|
```ts
|
|
241
241
|
// app-wide defaults (also fire for every HttpApi request)
|
|
242
242
|
fetchOrThrow.global.onRequest = ({ method, url }) => console.debug(`→ ${method} ${url}`);
|
|
243
|
-
fetchOrThrow.global.onError = ({ url, kind }) =>
|
|
244
|
-
kind !== "abort" && console.error(`✗ ${url}`); // kind: "abort" | "timeout" | "network"
|
|
243
|
+
fetchOrThrow.global.onError = ({ url, kind, reason }) =>
|
|
244
|
+
kind !== "abort" && console.error(`✗ ${url}: ${reason}`); // kind: "abort" | "timeout" | "network"
|
|
245
245
|
|
|
246
246
|
// per-call override (here: silence the global tracer for one call)
|
|
247
247
|
await fetchOrThrow(url, init, { what: "Token issuer", onRequest: () => {} });
|
package/dist/api.d.ts
CHANGED
|
@@ -151,6 +151,14 @@ export interface FetchOrThrowOptions {
|
|
|
151
151
|
url: string;
|
|
152
152
|
what?: string;
|
|
153
153
|
kind: "abort" | "timeout" | "network";
|
|
154
|
+
/**
|
|
155
|
+
* Human-readable failure reason, extracted via `getErrorMessage`. For a
|
|
156
|
+
* `network` failure this is the resolved transport reason embedded in the
|
|
157
|
+
* `NetworkError` message (e.g. `"ENOTFOUND"`); for `abort`/`timeout` it is
|
|
158
|
+
* the message of the original error. Always a string — handy for structured
|
|
159
|
+
* logging without re-parsing `error` yourself.
|
|
160
|
+
*/
|
|
161
|
+
reason: string;
|
|
154
162
|
}) => void;
|
|
155
163
|
}
|
|
156
164
|
/**
|
|
@@ -200,8 +208,8 @@ export type FetchOrThrowGlobalOptions = Pick<FetchOrThrowOptions, "onRequest" |
|
|
|
200
208
|
*
|
|
201
209
|
* // Configure tracing once, app-wide (also instruments the HttpApi client):
|
|
202
210
|
* fetchOrThrow.global.onRequest = ({ method, url }) => console.debug(`→ ${method} ${url}`);
|
|
203
|
-
* fetchOrThrow.global.onError = ({ url, kind }) =>
|
|
204
|
-
* kind !== "abort" && console.error(`✗ ${url}`);
|
|
211
|
+
* fetchOrThrow.global.onError = ({ url, kind, reason }) =>
|
|
212
|
+
* kind !== "abort" && console.error(`✗ ${url}: ${reason}`);
|
|
205
213
|
*
|
|
206
214
|
* try {
|
|
207
215
|
* const res = await fetchOrThrow("https://issuer.example.com/jwks", undefined, "Token issuer");
|
package/dist/api.js
CHANGED
|
@@ -228,15 +228,22 @@ const _FOT_GLOBAL =
|
|
|
228
228
|
onError: undefined,
|
|
229
229
|
});
|
|
230
230
|
/**
|
|
231
|
-
* Invoke an `onError` observer defensively: `url`
|
|
232
|
-
*
|
|
233
|
-
*
|
|
231
|
+
* Invoke an `onError` observer defensively: `url` and `reason` are only computed
|
|
232
|
+
* when a hook is present (the network path passes its already-resolved `reason`
|
|
233
|
+
* to avoid a second extraction), and a throwing hook is swallowed so it can never
|
|
234
|
+
* replace the real error that is about to propagate.
|
|
234
235
|
*/
|
|
235
|
-
function _notifyFetchError(hook, error, describe, input, what, kind) {
|
|
236
|
+
function _notifyFetchError(hook, error, describe, input, what, kind, reason) {
|
|
236
237
|
if (!hook)
|
|
237
238
|
return;
|
|
238
239
|
try {
|
|
239
|
-
hook({
|
|
240
|
+
hook({
|
|
241
|
+
error,
|
|
242
|
+
url: describe(input),
|
|
243
|
+
what,
|
|
244
|
+
kind,
|
|
245
|
+
reason: reason ?? getErrorMessage(error),
|
|
246
|
+
});
|
|
240
247
|
}
|
|
241
248
|
catch {
|
|
242
249
|
/* observer hooks must not alter control flow */
|
|
@@ -283,8 +290,8 @@ function _notifyFetchError(hook, error, describe, input, what, kind) {
|
|
|
283
290
|
*
|
|
284
291
|
* // Configure tracing once, app-wide (also instruments the HttpApi client):
|
|
285
292
|
* fetchOrThrow.global.onRequest = ({ method, url }) => console.debug(`→ ${method} ${url}`);
|
|
286
|
-
* fetchOrThrow.global.onError = ({ url, kind }) =>
|
|
287
|
-
* kind !== "abort" && console.error(`✗ ${url}`);
|
|
293
|
+
* fetchOrThrow.global.onError = ({ url, kind, reason }) =>
|
|
294
|
+
* kind !== "abort" && console.error(`✗ ${url}: ${reason}`);
|
|
288
295
|
*
|
|
289
296
|
* try {
|
|
290
297
|
* const res = await fetchOrThrow("https://issuer.example.com/jwks", undefined, "Token issuer");
|
|
@@ -332,7 +339,7 @@ export async function fetchOrThrow(input, init, what) {
|
|
|
332
339
|
? `${label} unreachable (${url}): ${reason}`
|
|
333
340
|
: `Network request to ${url} failed: ${reason}`;
|
|
334
341
|
const networkError = new NetworkError(message, { cause: underlying });
|
|
335
|
-
_notifyFetchError(onError, networkError, () => url, input, label, kind);
|
|
342
|
+
_notifyFetchError(onError, networkError, () => url, input, label, kind, reason);
|
|
336
343
|
throw networkError;
|
|
337
344
|
}
|
|
338
345
|
}
|