@sentry/api 0.353.0 → 0.356.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/README.md CHANGED
@@ -23,10 +23,10 @@ const sentry = createSentryClient({
23
23
  headers: { Authorization: `Bearer ${process.env.SENTRY_AUTH_TOKEN}` },
24
24
  });
25
25
 
26
- const { data, error } = await sentry.listOrganizations();
26
+ const result = await sentry.listOrganizations();
27
27
 
28
- if (error !== undefined) throw error;
29
- console.log(data);
28
+ if ("error" in result) throw result.error;
29
+ console.log(result.data);
30
30
  ```
31
31
 
32
32
  Operation methods retain the generated documentation, typed arguments, and response types. Per-call options include `path`, `query`, `headers`, `signal`, and `throwOnError`. Results preserve the underlying `request` and `response`, including response headers:
@@ -46,7 +46,9 @@ const { data: project, request, response } = await sentry.getProject({
46
46
  console.log(project, request.url, response.headers.get("content-type"));
47
47
  ```
48
48
 
49
- By default, operations return a `data`/`error` result. Set `throwOnError: true` to reject on errors, as above. Methods are bound to their instance and can be safely destructured, such as `const { getProject } = sentry`.
49
+ Operations always return `fields`: `{ data, request, response }` on success, or `{ error, request, response }` on failure. A failure without an HTTP response has `response: undefined`. Check `"error" in result`, since a custom error can itself be `undefined`. Received headers are in `response.headers`; outgoing headers are in `request.headers`.
50
+
51
+ Set `throwOnError: true` to reject on failures while keeping the same success fields. Methods are bound to their instance and can be safely destructured, such as `const { getProject } = sentry`. Types narrow to success when `true` is supplied **per call**; calls that inherit mutable client configuration conservatively retain the result union.
50
52
 
51
53
  Each `createSentryClient` call creates an independent transport configuration. The root entry also exports the `SentryClient` and `Config` types; `Config` is the underlying transport's configuration type. Access that transport as `sentry.client` for interceptors, configuration updates, or low-level requests.
52
54
 
@@ -82,6 +84,37 @@ const sentry = createSentryClient(
82
84
  const { data, error } = await sentry.listOrganizations();
83
85
  ```
84
86
 
87
+ ### Cancellation and custom fetch
88
+
89
+ Reuse the client and supply an `AbortSignal` for each operation. The caller owns the signal, whether it comes from a command, an MCP tool call, or a query library:
90
+
91
+ ```ts
92
+ const controller = new AbortController();
93
+ const pending = sentry.listOrganizations({
94
+ signal: controller.signal,
95
+ throwOnError: true,
96
+ });
97
+
98
+ // When this operation is no longer needed:
99
+ controller.abort();
100
+ await pending; // Rejects with the cancellation reason by default.
101
+ ```
102
+
103
+ Cancellation does not affect other calls sharing the client. Immediately before invoking `fetch`, the SDK checks the final request's signal, including changes made by request interceptors. An already-aborted signal prevents dispatch; authentication, validation, and request interceptors may still run before that check.
104
+
105
+ A configured `fetch` receives a native `Request`; its method, body, headers, and signal need not appear in a separate `init` argument. Forward the request intact and preserve native `RequestInit` override semantics when wrapping another transport:
106
+
107
+ ```ts
108
+ const sentry = createSentryClient({
109
+ baseUrl: "https://sentry.io",
110
+ fetch: (input, init) => fetch(input, init),
111
+ });
112
+ ```
113
+
114
+ Your transport must honor the signal while a request is in flight. The SDK cannot force an arbitrary custom fetch or asynchronous hook to stop, and cancellation does not undo a server mutation that has already completed.
115
+
116
+ Cancellation follows the [error handling contract](#error-handling): before dispatch the SDK uses `signal.reason`; during fetch it preserves the transport's rejection, which may differ by runtime. By default this is returned as `{ error, request, response: undefined }`, or thrown with `throwOnError: true`. Error interceptors can intentionally map it. Cancellation during response body reading rejects unchanged, even in fields mode. There is no SDK-specific cancellation error class.
117
+
85
118
  ## Runtime validation
86
119
 
87
120
  The root `@sentry/api` entry has no runtime dependencies. It provides the API client and pure TypeScript types without installing a validation library.
@@ -115,7 +148,43 @@ const project = zGetProjectResponse.parse(input);
115
148
 
116
149
  ## Error handling
117
150
 
118
- Every operation with documented error responses has a generated `narrowError_<operation>` wrapper. It returns data or a `SentryApiError` that preserves the operation's status-to-body type map. These wrappers remain standalone functions; pass `sentry.client` to reuse the client configured above:
151
+ HTTP failures use `SentryApiError`, whether returned in `result.error` or thrown with `throwOnError: true`. It preserves the status, parsed `body`, exact `rawBody` text, `request`, and `response` (including headers). The transport reads the error body once; consumers do not need to clone or reread the response. Error bodies without valid JSON remain strings.
152
+
153
+ ```ts
154
+ import { SentryApiError } from "@sentry/api";
155
+
156
+ const result = await sentry.listOrganizations();
157
+ if ("error" in result) {
158
+ if (result.error instanceof SentryApiError) {
159
+ console.log(result.error.status, result.error.body, result.error.rawBody);
160
+ console.log(result.error.response?.headers.get("retry-after"));
161
+ }
162
+ throw result.error;
163
+ }
164
+ ```
165
+
166
+ `error` is typed as `unknown`: a custom `fetch` or error interceptor can supply its own error. Fetch rejections, including cancellation, keep their original identity and have no HTTP response. They are returned or thrown according to `throwOnError`. Exceptions from serialization, validation, interceptors, or response body reading/decoding reject unchanged, even with `throwOnError: false`; that setting does not make a request exception-free.
167
+
168
+ ### Custom errors
169
+
170
+ HTTP errors are normalized **before** error interceptors run. Interceptors run in registration order, each receiving the preceding interceptor's result. Their returned or thrown value is preserved by operations and pagination; there is no second normalization pass.
171
+
172
+ ```ts
173
+ sentry.client.interceptors.error.use((error, response, request) => {
174
+ if (error instanceof SentryApiError) {
175
+ // Return your application's existing error type here, if needed.
176
+ return new Error(`API ${error.status}: ${request.method} ${request.url}`, {
177
+ cause: error,
178
+ });
179
+ }
180
+ // No HTTP response for a rejected fetch. Preserve cancellation/custom errors.
181
+ return error;
182
+ });
183
+ ```
184
+
185
+ ### Opt-in status narrowing
186
+
187
+ Every operation with documented error responses has a generated `narrowError_<operation>` wrapper. It narrows the default HTTP `SentryApiError` to the operation's status-to-body type map, preserving its metadata. These wrappers remain standalone functions; pass `sentry.client` to reuse the client configured above:
119
188
 
120
189
  ```ts
121
190
  import { narrowError_getProject } from "@sentry/api";
@@ -130,7 +199,7 @@ const result = await narrowError_getProject({
130
199
 
131
200
  if (!result.ok) {
132
201
  if (!result.error.documented) {
133
- // Unexpected HTTP status or a transport failure.
202
+ // Unexpected HTTP status.
134
203
  throw result.error;
135
204
  }
136
205
 
@@ -142,7 +211,17 @@ if (!result.ok) {
142
211
  }
143
212
  ```
144
213
 
145
- Checking `documented` first separates the operation's finite error union from unexpected statuses and transport failures. Within the documented branch, checking `status` narrows `body` to that response's schema. Error bodies remain `unknown` where the source OpenAPI response has no schema.
214
+ Checking `documented` first separates the operation's finite HTTP error union from unexpected statuses. Within the documented branch, checking `status` narrows `body` to that response's schema. This is a schema-based type assertion, **not runtime payload validation**. Error bodies remain `unknown` where the source OpenAPI response has no schema. Ordinary operations set `documented: false`; only these opt-in helpers know the operation's status map.
215
+
216
+ These helpers reclassify base `SentryApiError` instances belonging to the operation's response, including ones returned by an interceptor. Other errors—including custom classes/subclasses, fetch failures, cancellation, and decoding/validation exceptions—reject unchanged. They are not used implicitly by operations or pagination. Consumers that own their error model should use ordinary operations instead.
217
+
218
+ ### Migrating the 0.x response contract
219
+
220
+ - `responseStyle: "data"` is no longer accepted, including at initialization, `setConfig`, and per call. JavaScript callers receive a `TypeError` before a request is sent. Read `result.data` from the stable fields result instead.
221
+ - HTTP errors previously exposed a raw body; now read `error.body` after narrowing to `SentryApiError`. `error.rawBody` retains the original text.
222
+ - Successful results omit `error`; failed results include it even when the error value is falsy. Manual result fixtures must follow that shape. Use `"error" in result` rather than a truthiness check.
223
+ - Error interceptors receive normalized HTTP errors and chain their returned values. Pagination and `unwrapResult` no longer create another error or prepend a helper-specific message; their legacy `context` argument remains accepted.
224
+ - `narrowError_*` and `callWithTypedErrors` now narrow HTTP failures only. Other failures reject unchanged instead of becoming a synthetic transport `SentryApiError`. `SentryApiTransportError` remains a deprecated type alias, but is no longer part of `NarrowedResult`.
146
225
 
147
226
  ## Pagination
148
227
 
@@ -151,14 +230,16 @@ Sentry uses cursor-based pagination via `Link` headers. Choose one of three help
151
230
  | Task | Method | Result |
152
231
  | --- | --- | --- |
153
232
  | Display one page, with previous/next navigation | `sentry.fetchPage.<operation>(options, cursor?)` | `{ data, response, nextCursor?, prevCursor? }` |
154
- | Collect up to an item limit | `sentry.paginateUpTo.<operation>(options, { limit, ... })` | `{ data, nextCursor? }` |
155
- | Explicitly collect pages eagerly | `sentry.paginateAll.<operation>(options, { maxPages? }?)` | Concatenated array; stops at `maxPages` (default 50) |
233
+ | Collect up to an item limit | `sentry.paginateUpTo.<operation>(options, { limit, ... })` | `{ data, stopReason, nextCursor? }` |
234
+ | Explicitly collect pages eagerly | `sentry.paginateAll.<operation>(options, { maxPages?, startCursor? }?)` | `{ data, stopReason, nextCursor? }` |
156
235
 
157
236
  `fetchPage` is available for operations whose schema declares a `cursor` query parameter. Collection helpers are available only when the operation's 200 response is an array. Compound response bodies remain intact. Ordinary operation methods such as `sentry.listOrganizations()` still make just one request.
158
237
 
159
238
  All helpers reuse the instance's configuration and interceptors and can be destructured. They manage `cursor` separately from `query`, retaining your path, filters, and `signal` while invoking the configured operation. The SDK does not own page history or a response cache: the consumer keeps cursors in its URL, query cache, or persistent storage.
160
239
 
161
- Pagination needs the transport's default `responseStyle: "fields"` to read HTTP headers; `responseStyle: "data"` is not supported. Helpers reject on failure: under the default error policy, they throw `SentryApiError`; if the transport is configured with `throwOnError: true`, its thrown error propagates directly.
240
+ Pagination reads HTTP headers from the same fields contract. Helpers always reject on failure, preserving the exact error: `SentryApiError` for default HTTP failures, or the original custom error/cancellation. This is consistent whether `throwOnError` is enabled or disabled.
241
+
242
+ Generated collection helpers pass the same signal to every page operation. If it aborts between pages, the next page is not dispatched and the collection rejects; no partial collection is returned.
162
243
 
163
244
  ### Single page
164
245
 
@@ -182,35 +263,67 @@ Each page preserves its own raw `Response`, including status and headers. The tr
182
263
  ### Bounded collection
183
264
 
184
265
  ```ts
185
- const batch = await sentry.paginateUpTo.listOrganizationProjects(
186
- {
187
- path: { organization_id_or_slug: "my-org" },
188
- query: { per_page: 50 },
189
- },
190
- { limit: 250 },
191
- );
192
-
193
- console.log(batch.data, batch.nextCursor);
266
+ const options = { path: { organization_id_or_slug: "my-org" } };
267
+ const batch = await sentry.paginateUpTo.listOrganizationIssues(options, {
268
+ limit: 250,
269
+ maxPages: 5,
270
+ });
271
+ // Requests 100 + 100 + 50 when the server returns full pages.
272
+ console.log(batch.data, batch.stopReason);
273
+
274
+ if (batch.nextCursor !== undefined) {
275
+ const next = await sentry.paginateUpTo.listOrganizationIssues(options, {
276
+ limit: 250,
277
+ startCursor: batch.nextCursor,
278
+ });
279
+ }
194
280
  ```
195
281
 
196
- The total item limit and the HTTP page size are separate. Currently the helper uses the same requested page size for each request. If the last page overshoots the item limit, it trims the data and suppresses `nextCursor` by default to avoid skipping the discarded rows. The example uses 50-item HTTP pages for a 250-item budget.
282
+ Automatic sizing is deliberately limited to operations whose forward cursors have been verified to support changing page size:
283
+
284
+ | Operation | HTTP size parameter | Maximum per request |
285
+ | --- | --- | --- |
286
+ | `listOrganizationIssues`, `listProjectIssues` | `limit` | 100 |
287
+ | `listOrganizationIssueEvents` | `per_page` | 100; 10 with `full: true` |
288
+
289
+ Each request uses the smallest of the remaining item budget, the caller's requested page size (if supplied), and the verified maximum. Other operations retain their query options unchanged. In particular, **projects do not use 100 + 100 + 50**: their backend `OffsetPaginator` includes the page size in its cursor, and resizing mid-traversal can skip rows. Declaring `per_page` in the schema is not enough to enable resizing.
290
+
291
+ If a server ignores the size or an operation cannot be resized, the helper trims any excess rows and omits the unsafe cursor. It reports `stopReason: "limit"`, even if that was the server's last page. Use `fetchPage` when every row and each page's headers must be retained.
197
292
 
198
- ### Eager collection
293
+ ### Eager collection and completion
199
294
 
200
295
  ```ts
201
296
  const projects = await sentry.paginateAll.listOrganizationProjects(
202
297
  { path: { organization_id_or_slug: "my-org" } },
203
298
  { maxPages: 50 },
204
299
  );
300
+ console.log(projects.data, projects.stopReason);
301
+ // If stopReason is "maxPages", projects.nextCursor resumes traversal.
205
302
  ```
206
303
 
207
- Collection results do not expose a single `response`: their data can come from several HTTP requests. Use `fetchPage` when you need each page's headers or incremental loading.
304
+ Both collection helpers return `PaginatedCollection<TItem>`:
305
+
306
+ | `stopReason` | Meaning | `nextCursor` |
307
+ | --- | --- | --- |
308
+ | `"exhausted"` | All fetched rows were returned and the server advertises no next page | Absent |
309
+ | `"limit"` | The item budget stopped collection | Present only when no rows were discarded |
310
+ | `"maxPages"` | The request cap stopped collection while more pages exist | Present |
208
311
 
209
- ### Current collection limits
312
+ Only `stopReason === "exhausted"` means complete. If the final server page exactly fills the item budget, exhaustion takes precedence. A missing cursor alone does not mean complete.
210
313
 
211
- The bound methods preserve the existing helpers' behavior. `paginateAll` can return an incomplete array when it reaches `maxPages`, without identifying that condition. `paginateUpTo` also drops `nextCursor` when that cap is reached, so its absence does not prove the collection is exhausted. Use explicit page traversal when you need reliable exhaustion detection today.
314
+ `maxPages` defaults to 50 for both helpers. `limit` and `maxPages` must be positive safe integers. Resume forward from a returned `nextCursor`, keeping the same operation, filters, and page-size options; cursors stay opaque. SDK calls do not retain a history or snapshot the collection against concurrent server changes. Errors and cancellation reject the collection call, including after earlier pages succeeded.
212
315
 
213
- Operation-aware page sizing and explicit completion/continuation metadata are tracked in [#99](https://github.com/getsentry/sentry-api-schema/issues/99). Frontend query adapters and CLI navigation integration are also follow-up work. The existing `keepCursorOnOvershoot` escape hatch remains available for compatibility; its safety depends on the endpoint's cursor semantics.
316
+ Collection results have no single `response`: their data may come from several HTTP requests. Frontend tables and infinite queries can keep using `fetchPage` with their own URL/cache state. CLI history, MCP output budgets, and TanStack adapters remain consumer integrations tracked in [#99](https://github.com/getsentry/sentry-api-schema/issues/99).
317
+
318
+ ### Migration from earlier 0.x helpers
319
+
320
+ ```ts
321
+ // Before: const projects = await sentry.paginateAll.listOrganizationProjects(options);
322
+ const { data: projects, stopReason, nextCursor } =
323
+ await sentry.paginateAll.listOrganizationProjects(options);
324
+ ```
325
+
326
+ `paginateAll` now returns a collection object instead of an array, for bound, standalone, and generic helpers. `paginateUpTo` adds `stopReason` and preserves safe continuation at `maxPages`. The unsafe `keepCursorOnOvershoot` option has been removed; no cursor may skip discarded rows. Invalid item/request budgets now reject before fetching.
214
327
 
215
328
  ### Standalone pagination
216
329
 
@@ -237,6 +350,10 @@ The same low-level helpers used by the generated wrappers are also exported for
237
350
  - `unwrapPaginatedResult(sdkResult, context)` — same but with cursors
238
351
  - `fetchPage`, `paginateAll`, `paginateUpTo` — generic versions taking a fetcher thunk
239
352
 
353
+ A generic `paginateUpTo` fetcher receives `(cursor, remaining)`. Existing cursor-only fetchers still work; use `remaining` only when your endpoint's cursor supports resizing. The generated wrappers apply the verified rules above for you.
354
+
355
+ Generic helpers delegate cancellation to your fetcher. Pass its signal through to the operation or transport it invokes; the helper cannot cancel an arbitrary callback.
356
+
240
357
  ## Schema source
241
358
 
242
359
  The OpenAPI schema is synced from [`getsentry/sentry`](https://github.com/getsentry/sentry/tree/master/api-docs). Schema fixes belong there; build/tooling changes belong here.
@@ -1,8 +1,9 @@
1
+ import type { SdkResult } from '../sentry-errors';
1
2
  import type { Auth } from '../core/auth.gen';
2
3
  import type { ServerSentEventsOptions, ServerSentEventsResult } from '../core/serverSentEvents.gen';
3
4
  import type { Client as CoreClient, Config as CoreConfig } from '../core/types.gen';
4
5
  import type { Middleware } from './utils.gen';
5
- export type ResponseStyle = 'data' | 'fields';
6
+ export type ResponseStyle = 'fields';
6
7
  export interface Config<T extends ClientOptions = ClientOptions> extends Omit<RequestInit, 'body' | 'headers' | 'method'>, CoreConfig {
7
8
  /**
8
9
  * Base URL for all requests made by this client.
@@ -32,7 +33,7 @@ export interface Config<T extends ClientOptions = ClientOptions> extends Omit<Re
32
33
  */
33
34
  parseAs?: 'arrayBuffer' | 'auto' | 'blob' | 'formData' | 'json' | 'stream' | 'text';
34
35
  /**
35
- * Should we return only data or multiple fields (data, error, response, etc.)?
36
+ * Responses always include fields (data or error, request, response).
36
37
  *
37
38
  * @default 'fields'
38
39
  */
@@ -65,28 +66,19 @@ export interface RequestOptions<TData = unknown, TResponseStyle extends Response
65
66
  export interface ResolvedRequestOptions<TResponseStyle extends ResponseStyle = 'fields', ThrowOnError extends boolean = boolean, Url extends string = string> extends RequestOptions<unknown, TResponseStyle, ThrowOnError, Url> {
66
67
  serializedBody?: string;
67
68
  }
68
- export type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = ThrowOnError extends true ? Promise<TResponseStyle extends 'data' ? TData extends Record<string, unknown> ? TData[keyof TData] : TData : {
69
+ export type RequestResult<TData = unknown, TError = unknown, ThrowOnError extends boolean = boolean, TResponseStyle extends ResponseStyle = 'fields'> = Promise<ThrowOnError extends true ? {
69
70
  data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
70
71
  request: Request;
71
72
  response: Response;
72
- }> : Promise<TResponseStyle extends 'data' ? (TData extends Record<string, unknown> ? TData[keyof TData] : TData) | undefined : ({
73
- data: TData extends Record<string, unknown> ? TData[keyof TData] : TData;
74
- error: undefined;
75
- } | {
76
- data: undefined;
77
- error: TError extends Record<string, unknown> ? TError[keyof TError] : TError;
78
- }) & {
79
- request: Request;
80
- response: Response;
81
- }>;
73
+ } : SdkResult<TData extends Record<string, unknown> ? TData[keyof TData] : TData>>;
82
74
  export interface ClientOptions {
83
75
  baseUrl?: string;
84
76
  responseStyle?: ResponseStyle;
85
77
  throwOnError?: boolean;
86
78
  }
87
- type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
79
+ type MethodFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: (Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) & RequireThrowOnError<ThrowOnError>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
88
80
  type SseFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'>) => Promise<ServerSentEventsResult<TData, TError>>;
89
- type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
81
+ type RequestFn = <TData = unknown, TError = unknown, ThrowOnError extends boolean = false, TResponseStyle extends ResponseStyle = 'fields'>(options: (Omit<RequestOptions<TData, TResponseStyle, ThrowOnError>, 'method'> & Pick<Required<RequestOptions<TData, TResponseStyle, ThrowOnError>>, 'method'>) & RequireThrowOnError<ThrowOnError>) => RequestResult<TData, TError, ThrowOnError, TResponseStyle>;
90
82
  type BuildUrlFn = <TData extends {
91
83
  body?: unknown;
92
84
  path?: Record<string, unknown>;
@@ -113,5 +105,11 @@ export interface TDataShape {
113
105
  url: string;
114
106
  }
115
107
  type OmitKeys<T, K> = Pick<T, Exclude<keyof T, K>>;
116
- export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>);
108
+ export type Options<TData extends TDataShape = TDataShape, ThrowOnError extends boolean = boolean, TResponse = unknown, TResponseStyle extends ResponseStyle = 'fields'> = (OmitKeys<RequestOptions<TResponse, TResponseStyle, ThrowOnError>, 'body' | 'path' | 'query' | 'url'> & ([TData] extends [never] ? unknown : Omit<TData, 'url'>)) & RequireThrowOnError<ThrowOnError>;
109
+ /** Success-only types require a per-call runtime guarantee. */
110
+ type RequireThrowOnError<ThrowOnError extends boolean> = [
111
+ ThrowOnError
112
+ ] extends [true] ? {
113
+ throwOnError: true;
114
+ } : unknown;
117
115
  export {};
@@ -11,7 +11,7 @@ export declare const setAuthParams: ({ security, ...options }: Pick<Required<Req
11
11
  export declare const buildUrl: Client['buildUrl'];
12
12
  export declare const mergeConfigs: (a: Config, b: Config) => Config;
13
13
  export declare const mergeHeaders: (...headers: Array<Required<Config>["headers"] | undefined>) => Headers;
14
- type ErrInterceptor<Err, Res, Req, Options> = (error: Err, response: Res, request: Req, options: Options) => Err | Promise<Err>;
14
+ type ErrInterceptor<Err, Res, Req, Options> = (error: Err, response: Res | undefined, request: Req, options: Options) => Err | Promise<Err>;
15
15
  type ReqInterceptor<Req, Options> = (request: Req, options: Options) => Req | Promise<Req>;
16
16
  type ResInterceptor<Res, Req, Options> = (response: Res, request: Req, options: Options) => Res | Promise<Res>;
17
17
  declare class Interceptors<Interceptor> {