Skip to content

Commit 518d95a

Browse files
committedFeb 8, 2020
Fix unhandled errors if throwing in an async handler
1 parent 4f8c555 commit 518d95a

File tree

5 files changed

+31
-8
lines changed

5 files changed

+31
-8
lines changed
 

‎documentation/examples/gh-got.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
const got = require('../..');
33
const package = require('../../package');
44

5-
const getRateLimit = ({headers}) => ({
5+
const getRateLimit = (headers) => ({
66
limit: parseInt(headers['x-ratelimit-limit'], 10),
77
remaining: parseInt(headers['x-ratelimit-remaining'], 10),
88
reset: new Date(parseInt(headers['x-ratelimit-reset'], 10) * 1000)

‎documentation/lets-make-a-plugin.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ Umm... `response.headers['x-ratelimit-remaining']` doesn't look good. What about
161161
Yeah, definitely. Since `response.headers` is an object, we can easily parse these:
162162

163163
```js
164-
const getRateLimit = ({headers}) => ({
164+
const getRateLimit = (headers) => ({
165165
limit: parseInt(headers['x-ratelimit-limit'], 10),
166166
remaining: parseInt(headers['x-ratelimit-remaining'], 10),
167167
reset: new Date(parseInt(headers['x-ratelimit-reset'], 10) * 1000)
@@ -182,7 +182,7 @@ getRateLimit({
182182
Let's integrate it:
183183

184184
```js
185-
const getRateLimit = ({headers}) => ({
185+
const getRateLimit = (headers) => ({
186186
limit: parseInt(headers['x-ratelimit-limit'], 10),
187187
remaining: parseInt(headers['x-ratelimit-remaining'], 10),
188188
reset: new Date(parseInt(headers['x-ratelimit-reset'], 10) * 1000)

‎source/create.ts

+12-3
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,18 @@ const create = (defaults: Defaults): Got => {
113113
return root;
114114
});
115115

116-
if (result !== root && !options.isStream) {
117-
Object.setPrototypeOf(result, Object.getPrototypeOf(root));
118-
Object.defineProperties(result, Object.getOwnPropertyDescriptors(root));
116+
if (result !== root && !options.isStream && root) {
117+
const typedResult = result as Promise<unknown>;
118+
119+
const {then: promiseThen, catch: promiseCatch, finally: promiseFianlly} = typedResult;
120+
Object.setPrototypeOf(typedResult, Object.getPrototypeOf(root));
121+
Object.defineProperties(typedResult, Object.getOwnPropertyDescriptors(root));
122+
123+
// These should point to the new promise
124+
// eslint-disable-next-line promise/prefer-await-to-then
125+
typedResult.then = promiseThen;
126+
typedResult.catch = promiseCatch;
127+
typedResult.finally = promiseFianlly;
119128
}
120129

121130
return result;

‎source/types.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {URL} from 'url';
88
import {Readable as ReadableStream} from 'stream';
99
import {Timings, IncomingMessageWithTimings} from '@szmarczak/http-timer';
1010
import CacheableLookup from 'cacheable-lookup';
11-
import {Except, Merge, Promisable} from 'type-fest';
11+
import {Except, Merge} from 'type-fest';
1212
import {GotReturn} from './create';
1313
import {GotError, HTTPError, MaxRedirectsError, ParseError, TimeoutError, RequestError} from './errors';
1414
import {Hooks} from './known-hook-events';
@@ -77,7 +77,7 @@ export interface RetryObject {
7777

7878
export type RetryFunction = (retryObject: RetryObject) => number;
7979

80-
export type HandlerFunction = <T extends GotReturn>(options: NormalizedOptions, next: (options: NormalizedOptions) => T) => Promisable<T>;
80+
export type HandlerFunction = <T extends GotReturn>(options: NormalizedOptions, next: (options: NormalizedOptions) => T) => T | Promise<T>;
8181

8282
export interface DefaultRetryOptions {
8383
limit: number;

‎test/create.ts

+14
Original file line numberDiff line numberDiff line change
@@ -296,3 +296,17 @@ test('async handlers', withServer, async (t, server, got) => {
296296
// @ts-ignore Manual tests
297297
t.true((await promise).modified);
298298
});
299+
300+
test('async handlers can throw', async t => {
301+
const message = 'meh';
302+
303+
const instance = got.extend({
304+
handlers: [
305+
async () => {
306+
throw new Error(message);
307+
}
308+
]
309+
});
310+
311+
await t.throwsAsync(instance('https://example.com'), {message});
312+
});

0 commit comments

Comments
 (0)
Please sign in to comment.