vike 0.4.240-commit-bac5dee → 0.4.240-commit-098ff81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,7 +3,7 @@ export { getRenderCount };
3
3
  export { disableClientRouting };
4
4
  export { firstRenderStartPromise };
5
5
  export { getPageContextClient };
6
- import { assert, isSameErrorMessage, objectAssign, redirectHard, getGlobalObject, hasProp, updateType, genPromise, isCallable, catchInfiniteLoop, } from './utils.js';
6
+ import { assert, objectAssign, redirectHard, getGlobalObject, hasProp, updateType, genPromise, isCallable, catchInfiniteLoop, } from './utils.js';
7
7
  import { getPageContextFromClientHooks, getPageContextFromServerHooks, getPageContextFromHooks_isHydration, getPageContextFromHooks_serialized, setPageContextInitIsPassedToClient, } from './getPageContextFromHooks.js';
8
8
  import { createPageContextClientSide } from './createPageContextClientSide.js';
9
9
  import { addLinkPrefetchHandlers, addLinkPrefetchHandlers_unwatch, addLinkPrefetchHandlers_watch, getPageContextPrefetched, populatePageContextPrefetchCache, } from './prefetch.js';
@@ -60,7 +60,7 @@ async function renderPageClientSide(renderArgs) {
60
60
  return;
61
61
  async function renderPageNominal() {
62
62
  const onError = async (err) => {
63
- await renderPageOnError({ err });
63
+ await handleError({ err });
64
64
  };
65
65
  const pageContext = await getPageContextBegin(false, pageContextBeginArgs);
66
66
  if (isRenderOutdated())
@@ -229,96 +229,68 @@ async function renderPageClientSide(renderArgs) {
229
229
  await renderPageView(pageContext);
230
230
  }
231
231
  }
232
- // When the normal page threw an error
232
+ // When the normal page threw an error:
233
233
  // - Can be a URL rewrite upon `throw render('/some-url')`
234
234
  // - Can be rendering the error page
235
235
  // - Can be rendering Vike's generic error page (if no error page is defined, or if the error page throws an error)
236
- async function renderPageOnError(args) {
237
- const onError = (err) => {
238
- if (!isSameErrorMessage(err, args.err)) {
239
- /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
240
- - We risk running into an infinite loop of reloads which would overload the server.
241
- - An infinite reloading page is a even worse UX than a blank page.
242
- redirectHard(urlOriginal)
243
- */
244
- console.error(err);
245
- }
246
- };
247
- if ('err' in args) {
248
- const { err } = args;
249
- assert(err);
250
- if (!isAbortError(err)) {
251
- // We don't swallow 404 errors:
252
- // - On the server-side, Vike swallows / doesn't show any 404 error log because it's expected that a user may go to some random non-existent URL. (We don't want to flood the app's error tracking with 404 logs.)
253
- // - On the client-side, if the user navigates to a 404 then it means that the UI has a broken link. (It isn't expected that users can go to some random URL using the client-side router, as it would require, for example, the user to manually change the URL of a link by manually manipulating the DOM which highly unlikely.)
254
- console.error(err);
255
- }
256
- else {
257
- // We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
258
- // We handle the abort error down below.
259
- }
236
+ async function handleError(args) {
237
+ const { err } = args;
238
+ assert(err);
239
+ // Logging
240
+ if (!isAbortError(err)) {
241
+ // We don't swallow 404 errors:
242
+ // - On the server-side, Vike swallows / doesn't show any 404 error log because it's expected that a user may go to some random non-existent URL. (We don't want to flood the app's error tracking with 404 logs.)
243
+ // - On the client-side, if the user navigates to a 404 then it means that the UI has a broken link. (It isn't expected that users can go to some random URL using the client-side router, as it would require, for example, the user to manually change the URL of a link by manually manipulating the DOM which highly unlikely.)
244
+ console.error(err);
260
245
  }
246
+ else {
247
+ // We swallow throw redirect()/render() called by client-side hooks onBeforeRender()/data()/guard()
248
+ // We handle the abort error down below.
249
+ }
250
+ // pageContext
261
251
  const pageContext = await getPageContextBegin(true, pageContextBeginArgs);
262
252
  if (isRenderOutdated())
263
253
  return;
264
- objectAssign(pageContext, { routeParams: {} });
265
- if (args.pageContextError)
266
- objectAssign(pageContext, args.pageContextError);
267
- if ('err' in args) {
268
- const { err } = args;
269
- assert(!('errorWhileRendering' in pageContext));
270
- objectAssign(pageContext, { errorWhileRendering: err });
271
- if (isAbortError(err)) {
272
- const errAbort = err;
273
- logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
274
- const pageContextAbort = errAbort._pageContextAbort;
275
- // throw render('/some-url')
276
- if (pageContextAbort._urlRewrite) {
277
- await renderPageClientSide({
278
- ...renderArgs,
279
- scrollTarget: undefined,
280
- pageContextsFromRewrite: [...pageContextsFromRewrite, pageContextAbort],
281
- });
282
- return;
283
- }
284
- // throw redirect('/some-url')
285
- if (pageContextAbort._urlRedirect) {
286
- const urlRedirect = pageContextAbort._urlRedirect.url;
287
- if (!urlRedirect.startsWith('/')) {
288
- // External redirection
289
- redirectHard(urlRedirect);
290
- return;
291
- }
292
- else {
293
- await renderPageClientSide({
294
- ...renderArgs,
295
- scrollTarget: undefined,
296
- urlOriginal: urlRedirect,
297
- overwriteLastHistoryEntry: false,
298
- isBackwardNavigation: false,
299
- redirectCount: redirectCount + 1,
300
- });
301
- }
302
- return;
303
- }
304
- // throw render(statusCode)
305
- assert(pageContextAbort.abortStatusCode);
306
- assert(!('urlOriginal' in pageContextAbort));
307
- objectAssign(pageContext, pageContextAbort);
308
- if (pageContextAbort.abortStatusCode === 404) {
309
- objectAssign(pageContext, { is404: true });
310
- }
311
- }
312
- else {
313
- objectAssign(pageContext, { is404: false });
314
- }
254
+ objectAssign(pageContext, {
255
+ errorWhileRendering: err,
256
+ });
257
+ // throw redirect()/render()
258
+ let pageContextAbort;
259
+ if (isAbortError(err)) {
260
+ const res = await handleAbortError(err, pageContext);
261
+ if (res.skip)
262
+ return;
263
+ pageContextAbort = res.pageContextAbort;
315
264
  }
265
+ // Render error page
266
+ await renderErrorPage(pageContext, args, pageContextAbort);
267
+ }
268
+ async function renderErrorPage(pageContext, args, pageContextAbort) {
269
+ const onError = (err) => {
270
+ /* When we can't render the error page, we prefer showing a blank page over letting the server-side try because otherwise:
271
+ - We risk running into an infinite loop of reloads which would overload the server.
272
+ - An infinite reloading page is a even worse UX than a blank page.
273
+ redirectHard(urlOriginal)
274
+ */
275
+ console.error(err);
276
+ };
316
277
  const errorPageId = getErrorPageId(pageContext._pageFilesAll, pageContext._globalContext._pageConfigs);
317
278
  if (!errorPageId)
318
279
  throw new Error('No error page defined.');
319
280
  objectAssign(pageContext, {
320
281
  pageId: errorPageId,
282
+ routeParams: {},
321
283
  });
284
+ // throw render(statusCode)
285
+ if (pageContextAbort) {
286
+ assert(pageContextAbort.abortStatusCode);
287
+ assert(!('urlOriginal' in pageContextAbort));
288
+ objectAssign(pageContext, pageContextAbort);
289
+ objectAssign(pageContext, { is404: pageContextAbort.abortStatusCode === 404 });
290
+ }
291
+ else {
292
+ objectAssign(pageContext, { is404: false });
293
+ }
322
294
  const isClientRoutable = await isClientSideRoutable(pageContext.pageId, pageContext);
323
295
  if (isRenderOutdated())
324
296
  return;
@@ -326,6 +298,9 @@ async function renderPageClientSide(renderArgs) {
326
298
  redirectHard(urlOriginal);
327
299
  return;
328
300
  }
301
+ if (import.meta.env.DEV || globalThis.__VIKE__IS_DEBUG) {
302
+ assertInfo(false, `Rendering error page ${errorPageId}`, { onlyOnce: false });
303
+ }
329
304
  const res = await loadPageConfigsLazyClientSideAndExecHook(pageContext, isFirstRender, isRenderOutdated);
330
305
  /* Already called inside loadPageConfigsLazyClientSideAndExecHook()
331
306
  if (isRenderOutdated()) return
@@ -367,15 +342,49 @@ async function renderPageClientSide(renderArgs) {
367
342
  updateType(pageContext, pageContextFromClientHooks);
368
343
  await renderPageView(pageContext, args);
369
344
  }
345
+ async function handleAbortError(err, pageContext) {
346
+ const errAbort = err;
347
+ logAbortErrorHandled(err, !import.meta.env.DEV, pageContext);
348
+ const pageContextAbort = errAbort._pageContextAbort;
349
+ // throw render('/some-url')
350
+ if (pageContextAbort._urlRewrite) {
351
+ await renderPageClientSide({
352
+ ...renderArgs,
353
+ scrollTarget: undefined,
354
+ pageContextsFromRewrite: [...pageContextsFromRewrite, pageContextAbort],
355
+ });
356
+ return { skip: true };
357
+ }
358
+ // throw redirect('/some-url')
359
+ if (pageContextAbort._urlRedirect) {
360
+ const urlRedirect = pageContextAbort._urlRedirect.url;
361
+ if (!urlRedirect.startsWith('/')) {
362
+ // External redirection
363
+ redirectHard(urlRedirect);
364
+ return { skip: true };
365
+ }
366
+ else {
367
+ await renderPageClientSide({
368
+ ...renderArgs,
369
+ scrollTarget: undefined,
370
+ urlOriginal: urlRedirect,
371
+ overwriteLastHistoryEntry: false,
372
+ isBackwardNavigation: false,
373
+ redirectCount: redirectCount + 1,
374
+ });
375
+ }
376
+ return { skip: true };
377
+ }
378
+ // throw render(statusCode)
379
+ return { pageContextAbort };
380
+ }
370
381
  async function renderPageView(pageContext, isErrorPage) {
371
382
  const onError = async (err) => {
372
383
  if (!isErrorPage) {
373
- await renderPageOnError({ err });
384
+ await handleError({ err });
374
385
  }
375
386
  else {
376
- if (!isSameErrorMessage(err, isErrorPage.err)) {
377
- console.error(err);
378
- }
387
+ console.error(err);
379
388
  }
380
389
  };
381
390
  // We use globalObject.onRenderClientPreviousPromise in order to ensure that there is never two concurrent onRenderClient() calls
@@ -395,6 +404,7 @@ async function renderPageClientSide(renderArgs) {
395
404
  await execHookOnRenderClient(pageContext, preparePageContextForPublicUsageClient);
396
405
  }
397
406
  catch (err) {
407
+ assert(err);
398
408
  onRenderClientError = err;
399
409
  }
400
410
  globalObject.onRenderClientPreviousPromise = undefined;
@@ -7,7 +7,6 @@ export * from '../../utils/isCallable.js';
7
7
  export * from '../../utils/isObject.js';
8
8
  export * from '../../utils/isPlainObject.js';
9
9
  export * from '../../utils/isReact.js';
10
- export * from '../../utils/isSameErrorMessage.js';
11
10
  export * from '../../utils/objectAssign.js';
12
11
  export * from '../../utils/parseUrl.js';
13
12
  export * from '../../utils/PromiseType.js';
@@ -11,7 +11,6 @@ export * from '../../utils/isCallable.js';
11
11
  export * from '../../utils/isObject.js';
12
12
  export * from '../../utils/isPlainObject.js';
13
13
  export * from '../../utils/isReact.js';
14
- export * from '../../utils/isSameErrorMessage.js';
15
14
  export * from '../../utils/objectAssign.js';
16
15
  export * from '../../utils/parseUrl.js';
17
16
  export * from '../../utils/PromiseType.js';
@@ -12,6 +12,7 @@ export type { AbortStatusCode };
12
12
  export type { ErrorAbort };
13
13
  export type { PageContextFromRewrite };
14
14
  export type { UrlRedirect };
15
+ export type { PageContextAbort };
15
16
  type RedirectStatusCode = number & Parameters<typeof redirect>[1];
16
17
  type AbortStatusCode = number & Parameters<InferTwoOverloads<typeof render>[0]>[0];
17
18
  type UrlRedirect = {
@@ -1 +1 @@
1
- export declare const PROJECT_VERSION: "0.4.240-commit-bac5dee";
1
+ export declare const PROJECT_VERSION: "0.4.240-commit-098ff81";
@@ -1,2 +1,2 @@
1
1
  // Automatically updated by @brillout/release-me
2
- export const PROJECT_VERSION = '0.4.240-commit-bac5dee';
2
+ export const PROJECT_VERSION = '0.4.240-commit-098ff81';
@@ -36,7 +36,6 @@ const flags = [
36
36
  'vike:vite-rpc',
37
37
  ];
38
38
  const flagsSkipWildcard = ['vike:log'];
39
- const flagRegex = /\bvike:[a-zA-Z-]+/g;
40
39
  // We purposely read process.env.DEBUG early, in order to avoid users from the temptation to set process.env.DEBUG with JavaScript, since reading & writing process.env.DEBUG dynamically leads to inconsistencies such as https://github.com/vikejs/vike/issues/2239
41
40
  const DEBUG = getDEBUG() ?? '';
42
41
  if (isDebug())
@@ -86,8 +85,8 @@ function debug_(flag, options, ...msgs) {
86
85
  }
87
86
  function isDebugActivated(flag) {
88
87
  assert(flags.includes(flag));
89
- const { flagsActivated, all } = getFlagsActivated();
90
- const isActivated = flagsActivated.includes(flag) || (all && !flagsSkipWildcard.includes(flag));
88
+ const { flagsActivated, isAll } = getFlagsActivated();
89
+ const isActivated = flagsActivated.includes(flag) || (isAll && !flagsSkipWildcard.includes(flag));
91
90
  return isActivated;
92
91
  }
93
92
  function formatMsg(info, options, padding, position) {
@@ -156,17 +155,15 @@ function assertFlagsActivated() {
156
155
  assertUsage(flags.includes(flag), `Unknown DEBUG flag ${pc.cyan(flag)}. Valid flags:\n${flags.map((f) => ` ${pc.cyan(f)}`).join('\n')}`);
157
156
  });
158
157
  }
159
- // TODO/now: refactor isAll
160
- // TODO/now: refactor inline flagRegex
161
158
  function getFlagsActivated() {
162
- const flagsActivated = DEBUG.match(flagRegex) ?? [];
163
- const all = DEBUG.includes('vike:*');
159
+ const flagsActivated = DEBUG.match(/\bvike:[a-zA-Z-]+/g) ?? [];
160
+ const isAll = DEBUG.includes('vike:*');
164
161
  const isGlobal = /\bvike\b[^:]/.test(DEBUG);
165
- return { flagsActivated, all, isGlobal };
162
+ return { flagsActivated, isAll, isGlobal };
166
163
  }
167
164
  function isDebug() {
168
- const { flagsActivated, all, isGlobal } = getFlagsActivated();
169
- return all || flagsActivated.length > 0 || isGlobal;
165
+ const { flagsActivated, isAll, isGlobal } = getFlagsActivated();
166
+ return isAll || flagsActivated.length > 0 || isGlobal;
170
167
  }
171
168
  function getDEBUG() {
172
169
  let DEBUG;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vike",
3
- "version": "0.4.240-commit-bac5dee",
3
+ "version": "0.4.240-commit-098ff81",
4
4
  "repository": "https://github.com/vikejs/vike",
5
5
  "exports": {
6
6
  "./server": {
@@ -247,7 +247,7 @@
247
247
  "@types/source-map-support": "^0.5.10",
248
248
  "react-streaming": "^0.4.3",
249
249
  "rimraf": "^5.0.5",
250
- "typescript": "^5.8.3",
250
+ "typescript": "^5.9.2",
251
251
  "vite": "^7.1.5"
252
252
  },
253
253
  "scripts": {