Fix front-component cache read rejection bypassing network fallback (#22785)
## Summary Quick follow-up to #22672. `frontComponentCacheStorageService.read` returned `cachedResponse.text()` without awaiting it, so the promise escaped the surrounding `try/catch`. A cache entry with an unreadable body (corrupt or partially-evicted `CacheStorage` entry) would reject in `fetchComponentSource` and break component rendering entirely, instead of being treated as a cache miss with a network fallback. - `await` the body read inside the `try/catch` so decoding failures degrade to a network fetch - Add a regression test: cached body read rejects → source is still served from the network ## Test plan - `fetchComponentSource.spec.ts` — new test `falls back to the network when the cached response body is unreadable`; full renderer suite passes (14 tests) Made with [Cursor](https://cursor.com) <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/22785?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
+23
@@ -161,6 +161,29 @@ describe('fetchComponentSource', () => {
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('falls back to the network when the cached response body is unreadable', async () => {
|
||||
const cache = new FakeCache();
|
||||
|
||||
setupCaches(cache);
|
||||
|
||||
cache.match.mockResolvedValueOnce({
|
||||
text: async () => {
|
||||
throw new Error('body unreadable');
|
||||
},
|
||||
});
|
||||
|
||||
const fetchMock = jest.fn(async () =>
|
||||
createFakeJsResponse(COMPONENT_SOURCE),
|
||||
);
|
||||
|
||||
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
||||
|
||||
const source = await fetchComponentSource({ url: FINGERPRINTED_URL });
|
||||
|
||||
expect(source).toBe(COMPONENT_SOURCE);
|
||||
expect(fetchMock).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('does not cache a network response whose checksum does not match the URL', async () => {
|
||||
const cache = new FakeCache();
|
||||
|
||||
|
||||
+3
-1
@@ -48,7 +48,9 @@ export const frontComponentCacheStorageService = {
|
||||
try {
|
||||
const cachedResponse = await cache.match(url);
|
||||
|
||||
return isDefined(cachedResponse) ? cachedResponse.text() : undefined;
|
||||
return isDefined(cachedResponse)
|
||||
? await cachedResponse.text()
|
||||
: undefined;
|
||||
} catch {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user