Skip to content

Commit 3026a9c

Browse files
committed
feat: add result and args to onCacheUpdateError
1 parent 4e80242 commit 3026a9c

File tree

2 files changed

+42
-13
lines changed

2 files changed

+42
-13
lines changed

mod.test.ts

+36-11
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ import {
1212
stub,
1313
} from "jsr:@std/[email protected]/mock";
1414
import { FakeTime } from "jsr:@std/[email protected]/time";
15-
import { rememberPromise } from "./mod.ts";
15+
import { rememberPromise, type RememberPromiseOptions } from "./mod.ts";
1616

1717
const createMockPromiseFn = () => {
1818
let callCount = 1;
19-
return spy(() => Promise.resolve(`call-${callCount++}`));
19+
return spy((..._args: unknown[]) => Promise.resolve(`call-${callCount++}`));
2020
};
2121

2222
let time: FakeTime;
@@ -31,6 +31,7 @@ afterEach(() => {
3131

3232
it("should throttle calls to promiseFn", async () => {
3333
const promiseFn = createMockPromiseFn();
34+
3435
const cachedPromiseFn = rememberPromise(promiseFn);
3536

3637
assertEquals(await Promise.all([cachedPromiseFn(), cachedPromiseFn()]), [
@@ -43,6 +44,7 @@ it("should throttle calls to promiseFn", async () => {
4344
describe("ttl", () => {
4445
it("should never call promiseFn again if ttl is not set", async () => {
4546
const promiseFn = createMockPromiseFn();
47+
4648
const cachedPromiseFn = rememberPromise(promiseFn);
4749

4850
await cachedPromiseFn();
@@ -54,6 +56,7 @@ describe("ttl", () => {
5456

5557
it("should call promiseFn again if ttl is set and expired", async () => {
5658
const promiseFn = createMockPromiseFn();
59+
5760
const cachedPromiseFn = rememberPromise(promiseFn, { ttl: 30_000 });
5861

5962
await cachedPromiseFn();
@@ -65,6 +68,7 @@ describe("ttl", () => {
6568

6669
it("should not call promiseFn again if ttl is set and not expired", async () => {
6770
const promiseFn = createMockPromiseFn();
71+
6872
const cachedPromiseFn = rememberPromise(promiseFn, { ttl: 30_000 });
6973

7074
await cachedPromiseFn();
@@ -78,6 +82,7 @@ describe("ttl", () => {
7882
describe("allowStale", () => {
7983
it("should return previous cached result while updating cache after ttl expired and allowStale is true", async () => {
8084
const promiseFn = createMockPromiseFn();
85+
8186
const cachedPromiseFn = rememberPromise(promiseFn, {
8287
allowStale: true,
8388
ttl: 30_000,
@@ -92,6 +97,7 @@ describe("allowStale", () => {
9297

9398
it("should not return previous cached result while updating cache after ttl expired and allowStale is false", async () => {
9499
const promiseFn = createMockPromiseFn();
100+
95101
const cachedPromiseFn = rememberPromise(promiseFn, {
96102
allowStale: false,
97103
ttl: 30_000,
@@ -106,9 +112,10 @@ describe("allowStale", () => {
106112

107113
describe("cache", () => {
108114
it("should not call onCacheUpdateError or shouldIgnoreResult if cache is set to false", async () => {
115+
const promiseFn = createMockPromiseFn();
109116
const onCacheUpdateErrorSpy = spy(() => {});
110117
const shouldIgnoreResultSpy = spy(() => false);
111-
const promiseFn = createMockPromiseFn();
118+
112119
const cachedPromiseFn = rememberPromise(promiseFn, {
113120
cache: false,
114121
onCacheUpdateError: onCacheUpdateErrorSpy,
@@ -125,6 +132,7 @@ describe("cache", () => {
125132
describe("getCacheKey", () => {
126133
it("should use the same cached result if getCacheKey returns the same key", async () => {
127134
const promiseFn = createMockPromiseFn();
135+
128136
const cachedPromiseFn = rememberPromise(promiseFn, {
129137
getCacheKey: () => "",
130138
});
@@ -136,6 +144,7 @@ describe("getCacheKey", () => {
136144

137145
it("should not use the same cached result if getCacheKey returns a different key", async () => {
138146
const promiseFn = createMockPromiseFn();
147+
139148
const cachedPromiseFn = rememberPromise(promiseFn, {
140149
getCacheKey: stub(
141150
{ getCacheKey: () => "default" },
@@ -153,6 +162,7 @@ describe("getCacheKey", () => {
153162
describe("onCacheUpdateError", () => {
154163
describe("onCacheUpdateError is undefined", () => {
155164
it("should throw unhandled rejection if errors occurred while updating cache", async () => {
165+
const promiseFn = createMockPromiseFn();
156166
const cache = new Map();
157167
const cacheSetStub = stub(cache, "set", () => {
158168
throw new Error("test");
@@ -165,7 +175,7 @@ describe("onCacheUpdateError", () => {
165175
};
166176
globalThis.addEventListener("unhandledrejection", listener);
167177
});
168-
const promiseFn = createMockPromiseFn();
178+
169179
const cachedPromiseFn = rememberPromise(promiseFn, { cache });
170180

171181
assertEquals(await cachedPromiseFn(), "call-1");
@@ -175,6 +185,7 @@ describe("onCacheUpdateError", () => {
175185
});
176186

177187
it("should throw unhandled rejection if errors occurred while calling shouldIgnoreResult", async () => {
188+
const promiseFn = createMockPromiseFn();
178189
const shouldIgnoreResultSpy = spy(() => {
179190
throw new Error("test");
180191
});
@@ -186,7 +197,7 @@ describe("onCacheUpdateError", () => {
186197
};
187198
globalThis.addEventListener("unhandledrejection", listener);
188199
});
189-
const promiseFn = createMockPromiseFn();
200+
190201
const cachedPromiseFn = rememberPromise(promiseFn, {
191202
shouldIgnoreResult: shouldIgnoreResultSpy,
192203
});
@@ -200,47 +211,60 @@ describe("onCacheUpdateError", () => {
200211

201212
describe("onCacheUpdateError is defined", () => {
202213
it("should call onCacheUpdateError if errors occurred while updating cache", async () => {
214+
const promiseFn = createMockPromiseFn();
203215
const cache = new Map();
204216
const cacheSetStub = stub(cache, "set", () => {
205217
throw new Error("test");
206218
});
207-
const onCacheUpdateErrorSpy = spy((_error: unknown) => {});
208-
const promiseFn = createMockPromiseFn();
219+
const onCacheUpdateError: RememberPromiseOptions<
220+
typeof promiseFn
221+
>["onCacheUpdateError"] = () => {};
222+
const onCacheUpdateErrorSpy = spy(onCacheUpdateError);
223+
209224
const cachedPromiseFn = rememberPromise(promiseFn, {
210225
cache,
211226
onCacheUpdateError: onCacheUpdateErrorSpy,
212227
});
213228

214-
assertEquals(await cachedPromiseFn(), "call-1");
229+
assertEquals(await cachedPromiseFn("arg-1"), "call-1");
215230
assertSpyCalls(promiseFn, 1);
216231
assertSpyCalls(cacheSetStub, 1);
217232
assertSpyCalls(onCacheUpdateErrorSpy, 1);
218233
assertIsError(onCacheUpdateErrorSpy.calls[0].args[0], Error, "test");
234+
assertEquals(onCacheUpdateErrorSpy.calls[0].args[1], "call-1");
235+
assertEquals(onCacheUpdateErrorSpy.calls[0].args[2], ["arg-1"]);
219236
});
220237

221238
it("should call onCacheUpdateError if errors occurred while calling shouldIgnoreResult", async () => {
239+
const promiseFn = createMockPromiseFn();
222240
const shouldIgnoreResultSpy = spy(() => {
223241
throw new Error("test");
224242
});
225-
const onCacheUpdateErrorSpy = spy((_error: unknown) => {});
226-
const promiseFn = createMockPromiseFn();
243+
const onCacheUpdateError: RememberPromiseOptions<
244+
typeof promiseFn
245+
>["onCacheUpdateError"] = () => {};
246+
const onCacheUpdateErrorSpy = spy(onCacheUpdateError);
247+
227248
const cachedPromiseFn = rememberPromise(promiseFn, {
228249
shouldIgnoreResult: shouldIgnoreResultSpy,
229250
onCacheUpdateError: onCacheUpdateErrorSpy,
230251
});
231252

232-
assertEquals(await cachedPromiseFn(), "call-1");
253+
assertEquals(await cachedPromiseFn("arg-1"), "call-1");
233254
assertSpyCalls(promiseFn, 1);
234255
assertSpyCalls(shouldIgnoreResultSpy, 1);
235256
assertSpyCalls(onCacheUpdateErrorSpy, 1);
236257
assertIsError(onCacheUpdateErrorSpy.calls[0].args[0], Error, "test");
258+
assertEquals(onCacheUpdateErrorSpy.calls[0].args[1], "call-1");
259+
assertEquals(onCacheUpdateErrorSpy.calls[0].args[2], ["arg-1"]);
237260
});
238261
});
239262
});
240263

241264
describe("shouldIgnoreResult", () => {
242265
it("should update cache if shouldIgnoreResult returns false", async () => {
243266
const promiseFn = createMockPromiseFn();
267+
244268
const cachedPromiseFn = rememberPromise(promiseFn, {
245269
shouldIgnoreResult: (result) => result !== "call-1",
246270
ttl: 0,
@@ -253,6 +277,7 @@ describe("shouldIgnoreResult", () => {
253277

254278
it("should not update cache if shouldIgnoreResult returns true", async () => {
255279
const promiseFn = createMockPromiseFn();
280+
256281
const cachedPromiseFn = rememberPromise(promiseFn, {
257282
shouldIgnoreResult: (result) => result === "call-1",
258283
ttl: 0,

mod.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,11 @@ export interface RememberPromiseOptions<
107107
*
108108
* @default undefined
109109
*/
110-
onCacheUpdateError?: (err: unknown) => unknown;
110+
onCacheUpdateError?: (
111+
err: unknown,
112+
result: Result,
113+
args: Parameters<PromiseFn>,
114+
) => unknown;
111115
/**
112116
* Determines whether the returned result should be added to the cache.
113117
*
@@ -203,7 +207,7 @@ export function rememberPromise<
203207
}
204208
} catch (e) {
205209
if (onCacheUpdateError) {
206-
onCacheUpdateError(e);
210+
onCacheUpdateError(e, result, args);
207211
} else {
208212
throw e;
209213
}

0 commit comments

Comments
 (0)