Skip to content

Commit dfb8bcc

Browse files
Add optional url argument to didEncounterErrors hook (#242)
In previous versions of RESTDataSource, the URL of the request was available on the Request object passed in to the hook. The Request object is no longer passed as an argument, so this restores the availability of the url to the hook. This is optional for now in order to keep this change forward compatible for existing this.didEncounterErrors call sites in userland code. In the next major version, this might become a required parameter.
1 parent d2f0f5d commit dfb8bcc

File tree

4 files changed

+54
-2
lines changed

4 files changed

+54
-2
lines changed
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@apollo/datasource-rest': minor
3+
---
4+
5+
Add optional `url` parameter to `didEncounterErrors` hook
6+
7+
In previous versions of `RESTDataSource`, the URL of the request was available on the `Request` object passed in to the hook. The `Request` object is no longer passed as an argument, so this restores the availability of the `url` to the hook.
8+
9+
This is optional for now in order to keep this change forward compatible for existing `this.didEncounterErrors` call sites in userland code. In the next major version, this might become a required parameter.

cspell-dict.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,5 @@ pino
2222
revalidates
2323
singletonizes
2424
unmock
25+
userland
2526
withrequired

src/RESTDataSource.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,12 @@ export abstract class RESTDataSource {
261261
request: FetcherRequestInit,
262262
): ValueOrPromise<CacheOptions | undefined>;
263263

264-
protected didEncounterError(_error: Error, _request: RequestOptions) {
264+
protected didEncounterError(
265+
_error: Error,
266+
_request: RequestOptions,
267+
// TODO(v7): this shouldn't be optional in a future major version
268+
_url?: URL,
269+
) {
265270
// left as a no-op instead of an unimplemented optional method to avoid
266271
// breaking an existing use case where one calls
267272
// `super.didEncounterErrors(...)` This could be unimplemented / undefined
@@ -544,7 +549,7 @@ export abstract class RESTDataSource {
544549
},
545550
};
546551
} catch (error) {
547-
this.didEncounterError(error as Error, outgoingRequest);
552+
this.didEncounterError(error as Error, outgoingRequest, url);
548553
throw error;
549554
}
550555
});

src/__tests__/RESTDataSource.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2193,6 +2193,43 @@ describe('RESTDataSource', () => {
21932193
message: 'I replaced the error entirely',
21942194
});
21952195
});
2196+
2197+
it('is called with the url', async () => {
2198+
let urlFromDidEncounterError: URL | undefined = undefined;
2199+
const dataSource = new (class extends RESTDataSource {
2200+
override baseURL = 'https://api.example.com';
2201+
2202+
getFoo() {
2203+
return this.get('foo');
2204+
}
2205+
2206+
override didEncounterError(
2207+
_: Error,
2208+
__: RequestOptions,
2209+
url?: URL,
2210+
) {
2211+
urlFromDidEncounterError = url;
2212+
}
2213+
})();
2214+
2215+
nock(apiUrl)
2216+
.get('/foo')
2217+
.reply(
2218+
500,
2219+
{
2220+
errors: [{ message: 'Houston, we have a problem.' }],
2221+
},
2222+
{ 'content-type': 'application/json' },
2223+
);
2224+
2225+
try {
2226+
await dataSource.getFoo();
2227+
} catch {}
2228+
2229+
expect((urlFromDidEncounterError as any).toString()).toMatch(
2230+
'https://api.example.com/foo',
2231+
);
2232+
});
21962233
});
21972234
});
21982235
});

0 commit comments

Comments
 (0)