* Preserve the original error name instead of returning raw AbortError * use Error as the default error name
This commit is contained in:
parent
c23d770536
commit
6f6cc356f9
6 changed files with 47 additions and 12 deletions
|
@ -16,6 +16,7 @@ export interface IHttpFetchError extends Error
|
|||
| Property | Type | Description |
|
||||
| --- | --- | --- |
|
||||
| [body](./kibana-plugin-public.ihttpfetcherror.body.md) | <code>any</code> | |
|
||||
| [name](./kibana-plugin-public.ihttpfetcherror.name.md) | <code>string</code> | |
|
||||
| [req](./kibana-plugin-public.ihttpfetcherror.req.md) | <code>Request</code> | |
|
||||
| [request](./kibana-plugin-public.ihttpfetcherror.request.md) | <code>Request</code> | |
|
||||
| [res](./kibana-plugin-public.ihttpfetcherror.res.md) | <code>Response</code> | |
|
||||
|
|
|
@ -37,6 +37,7 @@ describe('Fetch', () => {
|
|||
});
|
||||
afterEach(() => {
|
||||
fetchMock.restore();
|
||||
fetchInstance.removeAllInterceptors();
|
||||
});
|
||||
|
||||
describe('http requests', () => {
|
||||
|
@ -287,6 +288,42 @@ describe('Fetch', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('preserves the name of the original error', async () => {
|
||||
expect.assertions(1);
|
||||
|
||||
const abortError = new DOMException('The operation was aborted.', 'AbortError');
|
||||
|
||||
fetchMock.get('*', Promise.reject(abortError));
|
||||
|
||||
await fetchInstance.fetch('/my/path').catch(e => {
|
||||
expect(e.name).toEqual('AbortError');
|
||||
});
|
||||
});
|
||||
|
||||
it('exposes the request to the interceptors in case of aborted request', async () => {
|
||||
const responseErrorSpy = jest.fn();
|
||||
const abortError = new DOMException('The operation was aborted.', 'AbortError');
|
||||
|
||||
fetchMock.get('*', Promise.reject(abortError));
|
||||
|
||||
fetchInstance.intercept({
|
||||
responseError: responseErrorSpy,
|
||||
});
|
||||
|
||||
await expect(fetchInstance.fetch('/my/path')).rejects.toThrow();
|
||||
|
||||
expect(responseErrorSpy).toHaveBeenCalledTimes(1);
|
||||
const interceptedResponse = responseErrorSpy.mock.calls[0][0];
|
||||
|
||||
expect(interceptedResponse.request).toEqual(
|
||||
expect.objectContaining({
|
||||
method: 'GET',
|
||||
url: 'http://localhost/myBase/my/path',
|
||||
})
|
||||
);
|
||||
expect(interceptedResponse.error.name).toEqual('AbortError');
|
||||
});
|
||||
|
||||
it('should support get() helper', async () => {
|
||||
fetchMock.get('*', {});
|
||||
await fetchInstance.get('/my/path', { method: 'POST' });
|
||||
|
@ -368,11 +405,6 @@ describe('Fetch', () => {
|
|||
fetchMock.get('*', { foo: 'bar' });
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
fetchMock.restore();
|
||||
fetchInstance.removeAllInterceptors();
|
||||
});
|
||||
|
||||
it('should make request and receive response', async () => {
|
||||
fetchInstance.intercept({});
|
||||
|
||||
|
|
|
@ -146,11 +146,7 @@ export class Fetch {
|
|||
try {
|
||||
response = await window.fetch(request);
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') {
|
||||
throw err;
|
||||
} else {
|
||||
throw new HttpFetchError(err.message, request);
|
||||
}
|
||||
throw new HttpFetchError(err.message, err.name ?? 'Error', request);
|
||||
}
|
||||
|
||||
const contentType = response.headers.get('Content-Type') || '';
|
||||
|
@ -170,11 +166,11 @@ export class Fetch {
|
|||
}
|
||||
}
|
||||
} catch (err) {
|
||||
throw new HttpFetchError(err.message, request, response, body);
|
||||
throw new HttpFetchError(err.message, err.name ?? 'Error', request, response, body);
|
||||
}
|
||||
|
||||
if (!response.ok) {
|
||||
throw new HttpFetchError(response.statusText, request, response, body);
|
||||
throw new HttpFetchError(response.statusText, 'Error', request, response, body);
|
||||
}
|
||||
|
||||
return { fetchOptions, request, response, body };
|
||||
|
|
|
@ -21,16 +21,19 @@ import { IHttpFetchError } from './types';
|
|||
|
||||
/** @internal */
|
||||
export class HttpFetchError extends Error implements IHttpFetchError {
|
||||
public readonly name: string;
|
||||
public readonly req: Request;
|
||||
public readonly res?: Response;
|
||||
|
||||
constructor(
|
||||
message: string,
|
||||
name: string,
|
||||
public readonly request: Request,
|
||||
public readonly response?: Response,
|
||||
public readonly body?: any
|
||||
) {
|
||||
super(message);
|
||||
this.name = name;
|
||||
this.req = request;
|
||||
this.res = response;
|
||||
|
||||
|
|
|
@ -291,6 +291,7 @@ export interface IHttpResponseInterceptorOverrides<TResponseBody = any> {
|
|||
|
||||
/** @public */
|
||||
export interface IHttpFetchError extends Error {
|
||||
readonly name: string;
|
||||
readonly request: Request;
|
||||
readonly response?: Response;
|
||||
/**
|
||||
|
|
|
@ -733,6 +733,8 @@ export type IContextProvider<THandler extends HandlerFunction<any>, TContextName
|
|||
export interface IHttpFetchError extends Error {
|
||||
// (undocumented)
|
||||
readonly body?: any;
|
||||
// (undocumented)
|
||||
readonly name: string;
|
||||
// @deprecated (undocumented)
|
||||
readonly req: Request;
|
||||
// (undocumented)
|
||||
|
|
Loading…
Reference in a new issue