Skip to content

Commit

Permalink
Handle Promise and Stream specific errors in beforeError hook
Browse files Browse the repository at this point in the history
Fixes #781
  • Loading branch information
szmarczak committed Apr 24, 2019
1 parent 6eaa81b commit 134c9b7
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 8 deletions.
24 changes: 18 additions & 6 deletions source/as-promise.ts
Expand Up @@ -24,19 +24,31 @@ export default function asPromise(options: Options) {

const promise = new PCancelable<IncomingMessage>((resolve, reject, onCancel) => {
const emitter = requestAsEventEmitter(options);

onCancel(emitter.abort);

const emitError = async (error: Error) => {
try {
for (const hook of options.hooks.beforeError) {
// eslint-disable-next-line no-await-in-loop
error = await hook(error);
}

reject(error);
} catch (error2) {
reject(error2);
}
};

emitter.on('response', async response => {
proxy.emit('response', response);

const stream = is.null_(options.encoding) ? getStream.buffer(response) : getStream(response, {encoding: options.encoding});

let data;
let data: Buffer | String;
try {
data = await stream;
} catch (error) {
reject(new ReadError(error, options));
emitError(new ReadError(error, options));
return;
}

Expand Down Expand Up @@ -69,7 +81,7 @@ export default function asPromise(options: Options) {
});
}
} catch (error) {
reject(error);
emitError(error);
return;
}

Expand All @@ -81,7 +93,7 @@ export default function asPromise(options: Options) {
} catch (error) {
if (statusCode >= 200 && statusCode < 300) {
const parseError = new ParseError(error, response, options);
reject(parseError);
emitError(parseError);
return;
}
}
Expand All @@ -91,7 +103,7 @@ export default function asPromise(options: Options) {
const error = new HTTPError(response, options);
if (emitter.retry(error) === false) {
if (options.throwHttpErrors) {
reject(error);
emitError(error);
return;
}

Expand Down
17 changes: 15 additions & 2 deletions source/as-stream.ts
Expand Up @@ -27,6 +27,19 @@ export default function asStream(options: MergedOptions) {

const emitter = requestAsEventEmitter(options, input);

const emitError = async (error: Error) => {
try {
for (const hook of options.hooks.beforeError) {
// eslint-disable-next-line no-await-in-loop
error = await hook(error);
}

proxy.emit('error', error);
} catch (error2) {
proxy.emit('error', error2);
}
};

// Cancels the request
proxy._destroy = (error, callback) => {
callback(error);
Expand All @@ -38,11 +51,11 @@ export default function asStream(options: MergedOptions) {
proxy.isFromCache = isFromCache;

response.on('error', error => {
proxy.emit('error', new ReadError(error, options));
emitError(new ReadError(error, options));
});

if (options.throwHttpErrors && statusCode !== 304 && (statusCode < 200 || statusCode > 299)) {
proxy.emit('error', new HTTPError(response, options), null, response);
emitError(new HTTPError(response, options));
return;
}

Expand Down
15 changes: 15 additions & 0 deletions test/hooks.ts
Expand Up @@ -498,3 +498,18 @@ test('does not break on `afterResponse` hook with JSON mode', withServer, async
responseType: 'json'
}));
});

test('catches HTTPErrors', withServer, async (t, _server, got) => {
t.plan(2);

await t.throwsAsync(got({
hooks: {
beforeError: [
(error: Error) => {
t.true(error instanceof got.HTTPError);
return error;
}
]
}
}));
});

0 comments on commit 134c9b7

Please sign in to comment.