Skip to content

Commit 29811db

Browse files
authored
[FIX] Fix case where priming a cache with an Error results in UnhandledPromiseRejection (#223)
1 parent 4212c9e commit 29811db

File tree

2 files changed

+41
-4
lines changed

2 files changed

+41
-4
lines changed

src/__tests__/dataloader.test.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,9 @@ describe('Represents Errors', () => {
341341

342342
identityLoader.prime(1, new Error('Error: 1'));
343343

344+
// Wait a bit.
345+
await new Promise(setImmediate);
346+
344347
let caughtErrorA;
345348
try {
346349
await identityLoader.load(1);
@@ -353,6 +356,35 @@ describe('Represents Errors', () => {
353356
expect(loadCalls).toEqual([]);
354357
});
355358

359+
// TODO: #224
360+
/*
361+
it('Not catching a primed error is an unhandled rejection', async () => {
362+
let hadUnhandledRejection = false;
363+
function onUnhandledRejection() {
364+
hadUnhandledRejection = true;
365+
}
366+
process.on('unhandledRejection', onUnhandledRejection);
367+
try {
368+
const [ identityLoader ] = idLoader<number>();
369+
370+
identityLoader.prime(1, new Error('Error: 1'));
371+
372+
// Wait a bit.
373+
await new Promise(setImmediate);
374+
375+
// Ignore result.
376+
identityLoader.load(1);
377+
378+
// Wait a bit.
379+
await new Promise(setImmediate);
380+
381+
expect(hadUnhandledRejection).toBe(true);
382+
} finally {
383+
process.removeListener('unhandledRejection', onUnhandledRejection);
384+
}
385+
});
386+
*/
387+
356388
it('Can clear values from cache after errors', async () => {
357389
const loadCalls = [];
358390
const errorLoader = new DataLoader(keys => {

src/index.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,10 +184,15 @@ class DataLoader<K, V, C = K> {
184184
if (cache.get(cacheKey) === undefined) {
185185
// Cache a rejected promise if the value is an Error, in order to match
186186
// the behavior of load(key).
187-
var promise = value instanceof Error ?
188-
Promise.reject(value) :
189-
Promise.resolve(value);
190-
187+
var promise;
188+
if (value instanceof Error) {
189+
promise = Promise.reject(value);
190+
// Since this is a case where an Error is intentionally being primed
191+
// for a given key, we want to disable unhandled promise rejection.
192+
promise.catch(() => {});
193+
} else {
194+
promise = Promise.resolve(value);
195+
}
191196
cache.set(cacheKey, promise);
192197
}
193198
}

0 commit comments

Comments
 (0)