Skip to content

Commit 23cd290

Browse files
committed
fix: handle q-data fetch error
1 parent 1ef59e9 commit 23cd290

File tree

3 files changed

+61
-4
lines changed

3 files changed

+61
-4
lines changed

packages/qwik-router/src/runtime/src/qwik-router-component.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,16 @@ export const QwikRouterProvider = component$<QwikRouterProps>((props) => {
177177
return env.response.loadersSerializationStrategy.get(loaderId) || 'never';
178178
};
179179

180+
// On server this object contains the all the loaders data
181+
// On client after resuming this object contains only keys and _UNINITIALIZED as values
182+
// Thanks to this we can use this object as a capture ref and not to serialize unneeded data
183+
// While resolving the loaders we will override the _UNINITIALIZED with the actual data
180184
const loadersObject: Record<string, unknown> = {};
185+
186+
// This object contains the signals for the loaders
187+
// It is used for the loaders context RouteStateContext
181188
const loaderState: Record<string, AsyncComputedReadonlySignal<unknown>> = {};
189+
182190
for (const [key, value] of Object.entries(env.response.loaders)) {
183191
loadersObject[key] = value;
184192
loaderState[key] = createLoaderSignal(
@@ -189,6 +197,7 @@ export const QwikRouterProvider = component$<QwikRouterProps>((props) => {
189197
container
190198
);
191199
}
200+
// Serialize it as keys and _UNINITIALIZED as values
192201
(loadersObject as any)[SerializerSymbol] = (obj: Record<string, unknown>) => {
193202
const loadersSerializationObject: Record<string, unknown> = {};
194203
for (const [k, v] of Object.entries(obj)) {

packages/qwik-router/src/runtime/src/utils.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { SimpleURL } from './types';
1+
import type { ClientPageData, SimpleURL } from './types';
22

33
import { createAsyncComputed$, isBrowser } from '@qwik.dev/core';
44
import {
@@ -112,9 +112,16 @@ export const createLoaderSignal = (
112112
return createAsyncComputed$(
113113
async () => {
114114
if (isBrowser && loadersObject[loaderId] === _UNINITIALIZED) {
115-
const data = await loadClientData(url, undefined, {
116-
loaderIds: [loaderId],
117-
});
115+
let data: ClientPageData | undefined;
116+
try {
117+
// Try to load only the current loader data from the server
118+
data = await loadClientData(url, undefined, {
119+
loaderIds: [loaderId],
120+
});
121+
} catch (_) {
122+
// If request fails, we try to load all the loaders data from the server
123+
data = await loadClientData(url, undefined);
124+
}
118125
loadersObject[loaderId] = data?.loaders[loaderId] ?? _UNINITIALIZED;
119126
}
120127
return loadersObject[loaderId];

starters/e2e/qwikrouter/loaders.e2e.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -180,5 +180,46 @@ test.describe("loaders", () => {
180180
);
181181
}
182182
});
183+
184+
test.only("should retry with all loaders if one fails", async ({
185+
page,
186+
javaScriptEnabled,
187+
}) => {
188+
let loadersRequestCount = 0;
189+
let allLoadersRequestCount = 0;
190+
page.on("request", (request) => {
191+
if (request.url().includes("q-data.json?qloaders")) {
192+
loadersRequestCount++;
193+
}
194+
if (request.url().endsWith("q-data.json")) {
195+
allLoadersRequestCount++;
196+
}
197+
});
198+
199+
await page.route(
200+
"*/**/qwikrouter-test/loaders-serialization/q-data.json?qloaders=HEA0jeovonw",
201+
async (route) => {
202+
await route.abort();
203+
},
204+
);
205+
await page.goto("/qwikrouter-test/loaders-serialization/");
206+
207+
if (javaScriptEnabled) {
208+
await page.locator("#toggle-child").click();
209+
await page.waitForLoadState("networkidle");
210+
expect(loadersRequestCount).toBe(1);
211+
expect(allLoadersRequestCount).toBe(1);
212+
await expect(page.locator("#prop1")).toHaveText("some test value");
213+
await expect(page.locator("#prop2")).toHaveText(
214+
"should not serialize this",
215+
);
216+
await expect(page.locator("#prop3")).toHaveText(
217+
"some eager test value",
218+
);
219+
await expect(page.locator("#prop4")).toHaveText(
220+
"should serialize this",
221+
);
222+
}
223+
});
183224
}
184225
});

0 commit comments

Comments
 (0)