Skip to content

Commit

Permalink
Setting code property on HTTPError object to be 'HTTPError' instead o…
Browse files Browse the repository at this point in the history
…f undefined
  • Loading branch information
Drewfergusson committed Jun 2, 2021
1 parent fbf9e69 commit e320a5a
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
111 changes: 111 additions & 0 deletions source/core/index.ts
Expand Up @@ -105,9 +105,120 @@ export type GotEventFunction<T> =
*/
& ((name: 'retry', listener: (retryCount: number, error: RequestError) => void) => T);

<<<<<<< HEAD
export interface RequestEvents<T> {
on: GotEventFunction<T>;
once: GotEventFunction<T>;
=======
Object.defineProperty(this, 'response', {
enumerable: false,
value: self[kResponse]
});

Object.defineProperty(this, 'options', {
// This fails because of TS 3.7.2 useDefineForClassFields
// Ref: https://github.com/microsoft/TypeScript/issues/34972
enumerable: false,
value: self.options
});
} else {
Object.defineProperty(this, 'options', {
// This fails because of TS 3.7.2 useDefineForClassFields
// Ref: https://github.com/microsoft/TypeScript/issues/34972
enumerable: false,
value: self
});
}

this.timings = this.request?.timings;

// Recover the original stacktrace
if (is.string(error.stack) && is.string(this.stack)) {
const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message!) + error.message!.length).split('\n').reverse();

// Remove duplicated traces
while (errorStackTrace.length !== 0 && errorStackTrace[0] === thisStackTrace[0]) {
thisStackTrace.shift();
}

this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`;
}
}
}

/**
An error to be thrown when the server redirects you more than ten times.
Includes a `response` property.
*/
export class MaxRedirectsError extends RequestError {
declare readonly response: Response;
declare readonly request: Request;
declare readonly timings: Timings;

constructor(request: Request) {
super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
this.name = 'MaxRedirectsError';
}
}

/**
An error to be thrown when the server response code is not 2xx nor 3xx if `options.followRedirect` is `true`, but always except for 304.
Includes a `response` property.
*/
export class HTTPError extends RequestError {
declare readonly response: Response;
declare readonly request: Request;
declare readonly timings: Timings;

constructor(response: Response) {
super(`Response code ${response.statusCode} (${response.statusMessage!})`, {}, response.request);
this.name = 'HTTPError';
this.code = 'HTTPError';
}
}
/**
An error to be thrown when a cache method fails.
For example, if the database goes down or there's a filesystem error.
*/
export class CacheError extends RequestError {
declare readonly request: Request;

constructor(error: Error, request: Request) {
super(error.message, error, request);
this.name = 'CacheError';
}
}

/**
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
*/
export class UploadError extends RequestError {
declare readonly request: Request;

constructor(error: Error, request: Request) {
super(error.message, error, request);
this.name = 'UploadError';
}
}

/**
An error to be thrown when the request is aborted due to a timeout.
Includes an `event` and `timings` property.
*/
export class TimeoutError extends RequestError {
declare readonly request: Request;
readonly timings: Timings;
readonly event: string;

constructor(error: TimedOutTimeoutError, timings: Timings, request: Request) {
super(error.message, error, request);
this.name = 'TimeoutError';
this.event = error.event;
this.timings = timings;
}
>>>>>>> f574d26... Setting code property on HTTPError object to be 'HTTPError' instead of undefined
}

export type CacheableRequestFunction = (
Expand Down
8 changes: 8 additions & 0 deletions test/error.ts
Expand Up @@ -26,7 +26,15 @@ test('properties', withServer, async (t, server, got) => {
t.truthy(error.options);
t.true({}.propertyIsEnumerable.call(error, 'options'));
t.false({}.propertyIsEnumerable.call(error, 'response'));
<<<<<<< HEAD
t.is(error.code, undefined);
=======
// This fails because of TS 3.7.2 useDefineForClassFields
// Class fields will always be initialized, even though they are undefined
// A test to check for undefined is in place below
// t.false({}.hasOwnProperty.call(error, 'code'));
t.is(error.code, 'HTTPError');
>>>>>>> f574d26... Setting code property on HTTPError object to be 'HTTPError' instead of undefined
t.is(error.message, 'Response code 404 (Not Found)');
t.deepEqual(error.options.url, url);
t.is(error.response.headers.connection, 'close');
Expand Down

0 comments on commit e320a5a

Please sign in to comment.