Skip to content

Commit e320a5a

Browse files
committed
Setting code property on HTTPError object to be 'HTTPError' instead of undefined
1 parent fbf9e69 commit e320a5a

2 files changed

Lines changed: 119 additions & 0 deletions

File tree

source/core/index.ts

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,120 @@ export type GotEventFunction<T> =
105105
*/
106106
& ((name: 'retry', listener: (retryCount: number, error: RequestError) => void) => T);
107107

108+
<<<<<<< HEAD
108109
export interface RequestEvents<T> {
109110
on: GotEventFunction<T>;
110111
once: GotEventFunction<T>;
112+
=======
113+
Object.defineProperty(this, 'response', {
114+
enumerable: false,
115+
value: self[kResponse]
116+
});
117+
118+
Object.defineProperty(this, 'options', {
119+
// This fails because of TS 3.7.2 useDefineForClassFields
120+
// Ref: https://github.com/microsoft/TypeScript/issues/34972
121+
enumerable: false,
122+
value: self.options
123+
});
124+
} else {
125+
Object.defineProperty(this, 'options', {
126+
// This fails because of TS 3.7.2 useDefineForClassFields
127+
// Ref: https://github.com/microsoft/TypeScript/issues/34972
128+
enumerable: false,
129+
value: self
130+
});
131+
}
132+
133+
this.timings = this.request?.timings;
134+
135+
// Recover the original stacktrace
136+
if (is.string(error.stack) && is.string(this.stack)) {
137+
const indexOfMessage = this.stack.indexOf(this.message) + this.message.length;
138+
const thisStackTrace = this.stack.slice(indexOfMessage).split('\n').reverse();
139+
const errorStackTrace = error.stack.slice(error.stack.indexOf(error.message!) + error.message!.length).split('\n').reverse();
140+
141+
// Remove duplicated traces
142+
while (errorStackTrace.length !== 0 && errorStackTrace[0] === thisStackTrace[0]) {
143+
thisStackTrace.shift();
144+
}
145+
146+
this.stack = `${this.stack.slice(0, indexOfMessage)}${thisStackTrace.reverse().join('\n')}${errorStackTrace.reverse().join('\n')}`;
147+
}
148+
}
149+
}
150+
151+
/**
152+
An error to be thrown when the server redirects you more than ten times.
153+
Includes a `response` property.
154+
*/
155+
export class MaxRedirectsError extends RequestError {
156+
declare readonly response: Response;
157+
declare readonly request: Request;
158+
declare readonly timings: Timings;
159+
160+
constructor(request: Request) {
161+
super(`Redirected ${request.options.maxRedirects} times. Aborting.`, {}, request);
162+
this.name = 'MaxRedirectsError';
163+
}
164+
}
165+
166+
/**
167+
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.
168+
Includes a `response` property.
169+
*/
170+
export class HTTPError extends RequestError {
171+
declare readonly response: Response;
172+
declare readonly request: Request;
173+
declare readonly timings: Timings;
174+
175+
constructor(response: Response) {
176+
super(`Response code ${response.statusCode} (${response.statusMessage!})`, {}, response.request);
177+
this.name = 'HTTPError';
178+
this.code = 'HTTPError';
179+
}
180+
}
181+
/**
182+
An error to be thrown when a cache method fails.
183+
For example, if the database goes down or there's a filesystem error.
184+
*/
185+
export class CacheError extends RequestError {
186+
declare readonly request: Request;
187+
188+
constructor(error: Error, request: Request) {
189+
super(error.message, error, request);
190+
this.name = 'CacheError';
191+
}
192+
}
193+
194+
/**
195+
An error to be thrown when the request body is a stream and an error occurs while reading from that stream.
196+
*/
197+
export class UploadError extends RequestError {
198+
declare readonly request: Request;
199+
200+
constructor(error: Error, request: Request) {
201+
super(error.message, error, request);
202+
this.name = 'UploadError';
203+
}
204+
}
205+
206+
/**
207+
An error to be thrown when the request is aborted due to a timeout.
208+
Includes an `event` and `timings` property.
209+
*/
210+
export class TimeoutError extends RequestError {
211+
declare readonly request: Request;
212+
readonly timings: Timings;
213+
readonly event: string;
214+
215+
constructor(error: TimedOutTimeoutError, timings: Timings, request: Request) {
216+
super(error.message, error, request);
217+
this.name = 'TimeoutError';
218+
this.event = error.event;
219+
this.timings = timings;
220+
}
221+
>>>>>>> f574d26... Setting code property on HTTPError object to be 'HTTPError' instead of undefined
111222
}
112223

113224
export type CacheableRequestFunction = (

test/error.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,15 @@ test('properties', withServer, async (t, server, got) => {
2626
t.truthy(error.options);
2727
t.true({}.propertyIsEnumerable.call(error, 'options'));
2828
t.false({}.propertyIsEnumerable.call(error, 'response'));
29+
<<<<<<< HEAD
2930
t.is(error.code, undefined);
31+
=======
32+
// This fails because of TS 3.7.2 useDefineForClassFields
33+
// Class fields will always be initialized, even though they are undefined
34+
// A test to check for undefined is in place below
35+
// t.false({}.hasOwnProperty.call(error, 'code'));
36+
t.is(error.code, 'HTTPError');
37+
>>>>>>> f574d26... Setting code property on HTTPError object to be 'HTTPError' instead of undefined
3038
t.is(error.message, 'Response code 404 (Not Found)');
3139
t.deepEqual(error.options.url, url);
3240
t.is(error.response.headers.connection, 'close');

0 commit comments

Comments
 (0)