Skip to content

Commit eee91c9

Browse files
committed
Add warnings
1 parent b4fbacd commit eee91c9

File tree

3 files changed

+61
-15
lines changed

3 files changed

+61
-15
lines changed

packages/plugins/response-cache-cloudflare-kv/src/index.ts

+46-12
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ export function createKvCache<
3838
} & {
3939
waitUntil(promise: Promise<unknown>): void;
4040
},
41-
>(config: KvCacheConfig<TKVNamespaceName>): (ctx: TServerContext) => Cache {
41+
>(config: KvCacheConfig<TKVNamespaceName>) {
4242
if (config.cacheReadTTL && config.cacheReadTTL < 60000) {
4343
// eslint-disable-next-line no-console
4444
console.warn(
@@ -47,17 +47,21 @@ export function createKvCache<
4747
}
4848
const computedTtlInSeconds = Math.max(Math.floor((config.cacheReadTTL ?? 60000) / 1000), 60); // KV TTL must be at least 60 seconds
4949

50-
return function KVCacheFactory(ctx: TServerContext) {
50+
return function KVCacheFactory(ctx: TServerContext): Cache {
5151
return {
52-
async get(id: string) {
53-
const kvResponse = await ctx[config.KVName].get(buildOperationKey(id, config.keyPrefix), {
54-
type: 'text',
52+
get(id: string) {
53+
if (!ctx[config.KVName]) {
54+
// eslint-disable-next-line no-console
55+
console.warn(
56+
`Cloudflare KV namespace ${config.KVName} is not available in the server context, skipping cache read.`,
57+
);
58+
return;
59+
}
60+
const operationKey = buildOperationKey(id, config.keyPrefix);
61+
return ctx[config.KVName].get(operationKey, {
62+
type: 'json',
5563
cacheTtl: computedTtlInSeconds,
5664
});
57-
if (kvResponse) {
58-
return JSON.parse(kvResponse) as ExecutionResult;
59-
}
60-
return undefined;
6165
},
6266

6367
set(
@@ -69,12 +73,42 @@ export function createKvCache<
6973
entities: Iterable<CacheEntityRecord>,
7074
/** how long the operation should be cached (in milliseconds) */
7175
ttl: number,
72-
) {
76+
): void | Promise<void> {
77+
if (!ctx[config.KVName]) {
78+
// eslint-disable-next-line no-console
79+
console.warn(
80+
`Cloudflare KV namespace ${config.KVName} is not available in the server context, skipping cache write.`,
81+
);
82+
return;
83+
}
84+
const setPromise = set(id, data, entities, ttl, ctx[config.KVName], config.keyPrefix);
85+
if (!ctx.waitUntil) {
86+
// eslint-disable-next-line no-console
87+
console.warn(
88+
'The server context does not have a waitUntil method. This means that the cache write will not be non-blocking.',
89+
);
90+
return setPromise;
91+
}
7392
// Do not block execution of the worker while caching the result
74-
ctx.waitUntil(set(id, data, entities, ttl, ctx[config.KVName], config.keyPrefix));
93+
ctx.waitUntil(setPromise);
7594
},
7695

77-
invalidate(entities: Iterable<CacheEntityRecord>) {
96+
invalidate(entities: Iterable<CacheEntityRecord>): void | Promise<void> {
97+
if (!ctx[config.KVName]) {
98+
// eslint-disable-next-line no-console
99+
console.warn(
100+
`Cloudflare KV namespace ${config.KVName} is not available in the server context, skipping cache invalidate.`,
101+
);
102+
return;
103+
}
104+
const invalidatePromise = invalidate(entities, ctx[config.KVName], config.keyPrefix);
105+
if (!ctx.waitUntil) {
106+
// eslint-disable-next-line no-console
107+
console.warn(
108+
'The server context does not have a waitUntil method. This means that the cache invalidation will not be non-blocking.',
109+
);
110+
return invalidatePromise;
111+
}
78112
// Do not block execution of the worker while invalidating the cache
79113
ctx.waitUntil(invalidate(entities, ctx[config.KVName], config.keyPrefix));
80114
},

packages/plugins/response-cache-cloudflare-kv/test/index.spec.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ describe('@envelop/response-cache-cloudflare-kv integration tests', () => {
6060

6161
test('should return null when calling get() on a non-existent key', async () => {
6262
const result = await cache.get(dataKey);
63-
expect(result).toBeUndefined();
63+
expect(result).toBeFalsy();
6464
});
6565

6666
test('should return null when calling get() on an invalidated key', async () => {
@@ -78,7 +78,7 @@ describe('@envelop/response-cache-cloudflare-kv integration tests', () => {
7878
await getMiniflareWaitUntil(executionContext);
7979

8080
const result = await cache.get(dataKey);
81-
expect(result).toBeUndefined();
81+
expect(result).toBeFalsy();
8282

8383
const allKeys = await KV.list();
8484
expect(allKeys.keys.length).toEqual(0);

packages/plugins/response-cache/src/plugin.ts

+13-1
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,13 @@ export function useResponseCache<PluginContext extends Record<string, any> = {}>
480480
processResult(result.data);
481481

482482
const cacheInstance = cacheFactory(onExecuteParams.args.contextValue);
483+
if (cacheInstance == null) {
484+
// eslint-disable-next-line no-console
485+
console.warn(
486+
'[useResponseCache] Cache instance is not available for the context. Skipping invalidation.',
487+
);
488+
return;
489+
}
483490
cacheInstance.invalidate(identifier.values());
484491
if (includeExtensionMetadata) {
485492
setResult(
@@ -527,6 +534,12 @@ export function useResponseCache<PluginContext extends Record<string, any> = {}>
527534
});
528535

529536
const cacheInstance = cacheFactory(onExecuteParams.args.contextValue);
537+
if (cacheInstance == null) {
538+
// eslint-disable-next-line no-console
539+
console.warn(
540+
'[useResponseCache] Cache instance is not available for the context. Skipping cache lookup.',
541+
);
542+
}
530543
const cachedResponse = (await cacheInstance.get(cacheKey)) as ResponseCacheExecutionResult;
531544

532545
if (cachedResponse != null) {
@@ -553,7 +566,6 @@ export function useResponseCache<PluginContext extends Record<string, any> = {}>
553566
return;
554567
}
555568

556-
const cacheInstance = cacheFactory(onExecuteParams.args.contextValue);
557569
cacheInstance.set(cacheKey, result, identifier.values(), finalTtl);
558570
if (includeExtensionMetadata) {
559571
setResult(resultWithMetadata(result, { hit: false, didCache: true, ttl: finalTtl }));

0 commit comments

Comments
 (0)