@wular/pnext 0.0.4 → 0.0.6
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.
- package/README.md +11 -11
- package/bin/pnext +1 -1
- package/config/lint/base.js +7 -7
- package/config/ts/base.json +2 -4
- package/config/ts/react.json +2 -6
- package/package.json +23 -2
- package/reference/compat.md +1 -1
- package/reference/config.md +2 -2
- package/reference/css.md +13 -9
- package/reference/dev.md +1 -1
- package/reference/metadata.md +7 -7
- package/reference/navigation.md +35 -28
- package/reference/performance.md +70 -70
- package/reference/rendering.md +17 -17
- package/reference/routing.md +17 -17
- package/reference/typegen.md +12 -8
- package/src/api/cache.ts +36 -37
- package/src/api/client-cache.ts +2 -2
- package/src/api/client-navigation.ts +113 -109
- package/src/api/dynamic.tsx +58 -55
- package/src/api/link.tsx +49 -52
- package/src/api/navigation.ts +59 -58
- package/src/api/server.ts +152 -144
- package/src/api/suspense.ts +4 -4
- package/src/cli/adapters/vercel-warm.ts +126 -121
- package/src/cli/adapters/vercel.ts +437 -443
- package/src/cli/analyze.ts +333 -144
- package/src/cli/{named-bin.ts → boot/named-bin.ts} +37 -37
- package/src/cli/{boot-trace.ts → boot/trace.ts} +10 -10
- package/src/cli/build.ts +976 -978
- package/src/cli/create.ts +71 -63
- package/src/cli/dev.ts +116 -116
- package/src/cli/index.ts +88 -85
- package/src/cli/migrate/package-json.ts +73 -71
- package/src/cli/migrate/report.ts +32 -33
- package/src/cli/migrate/{index.ts → run.ts} +48 -49
- package/src/cli/migrate/scan.ts +46 -46
- package/src/cli/migrate/spinner.ts +9 -9
- package/src/cli/migrate/tsconfig.ts +35 -35
- package/src/cli/{server-entry.ts → serve/entry.ts} +57 -57
- package/src/cli/{request-pipeline.ts → serve/pipeline.ts} +386 -394
- package/src/cli/{serve-ui.ts → serve/ui.ts} +47 -47
- package/src/cli/start.ts +65 -66
- package/src/{typegen.ts → cli/typegen.ts} +59 -59
- package/src/client/build.ts +794 -768
- package/src/client/chunk-fold.ts +245 -240
- package/src/client/{paths.ts → chunk-name.ts} +6 -6
- package/src/client/entry.ts +162 -147
- package/src/client/prebuilt.ts +231 -223
- package/src/client/profile.ts +29 -29
- package/src/client/react-compiler.ts +20 -15
- package/src/client/{compat-surface.ts → react-tier.ts} +64 -64
- package/src/client/reference-stub.ts +51 -51
- package/src/client/reference.ts +19 -19
- package/src/{api → client}/router/events.ts +17 -17
- package/src/{api → client}/router/history.ts +16 -16
- package/src/{api → client}/router/hub.ts +52 -53
- package/src/{api/router.ts → client/router/index.ts} +61 -60
- package/src/{api → client}/router/policies.ts +24 -24
- package/src/{api → client}/router/runtime.ts +1988 -1992
- package/src/{api → client}/router/types.ts +93 -98
- package/src/compat/actions/client-plugin.ts +42 -43
- package/src/compat/actions/client-stub.ts +14 -14
- package/src/compat/actions/{action-client.ts → client.ts} +194 -193
- package/src/compat/actions/config.ts +63 -64
- package/src/compat/actions/detect.ts +68 -68
- package/src/compat/actions/discovery.ts +105 -105
- package/src/compat/actions/{action-dispatch.ts → dispatch.ts} +277 -274
- package/src/compat/actions/early-submit.ts +1 -1
- package/src/compat/actions/endpoint.ts +198 -198
- package/src/compat/actions/extensions.ts +811 -0
- package/src/compat/actions/flight.ts +23 -23
- package/src/compat/actions/form-state.ts +34 -34
- package/src/compat/actions/hoist.ts +382 -236
- package/src/compat/actions/ids.ts +7 -12
- package/src/compat/actions/index.ts +8 -8
- package/src/compat/actions/instances.ts +46 -46
- package/src/compat/actions/origin.ts +47 -48
- package/src/compat/actions/protocol.ts +22 -22
- package/src/compat/actions/registry.ts +19 -19
- package/src/compat/{misc/action-return.ts → actions/return.ts} +60 -57
- package/src/compat/actions/rewrite.ts +125 -125
- package/src/compat/actions/{action-router.ts → router.ts} +10 -10
- package/src/compat/actions/serve.ts +132 -136
- package/src/compat/actions/server-tag.ts +4 -4
- package/src/compat/actions/{action-shared.ts → shared.ts} +34 -34
- package/src/compat/actions/unrecognized-error.ts +4 -4
- package/src/compat/{index.ts → aliases.ts} +112 -109
- package/src/compat/bundler/bun-externals.ts +18 -18
- package/src/compat/bundler/cjs-exports.ts +271 -223
- package/src/compat/bundler/config.ts +116 -111
- package/src/compat/bundler/externals.ts +12 -12
- package/src/compat/bundler/import-meta-url.ts +19 -19
- package/src/compat/bundler/modularize-imports.ts +36 -33
- package/src/compat/bundler/new-url-asset.ts +22 -24
- package/src/compat/bundler/optimize-package-imports.ts +111 -107
- package/src/compat/bundler/polyfill.ts +28 -28
- package/src/compat/bundler/react-compiler.ts +35 -29
- package/src/compat/bundler/react-profiler.tsx +11 -11
- package/src/compat/bundler/relay-transform.ts +48 -47
- package/src/compat/bundler/require-context.ts +119 -113
- package/src/compat/bundler/resolve-extensions.ts +19 -19
- package/src/compat/bundler/source-cache.ts +25 -25
- package/src/compat/bundler/static-imports.ts +7 -7
- package/src/compat/bundler/symlink-imports.ts +46 -46
- package/src/compat/bundler/tsconfig-paths.ts +13 -15
- package/src/compat/bundler/wasm.ts +58 -60
- package/src/compat/bundler/webpack-loaders.ts +254 -241
- package/src/compat/bundler/worker.ts +101 -104
- package/src/compat/cache/build-flags.ts +29 -29
- package/src/compat/cache/build-prerender-errors.ts +40 -44
- package/src/compat/cache/custom-handler.ts +60 -53
- package/src/compat/cache/fetch-patch.ts +240 -240
- package/src/compat/cache/handler.ts +27 -31
- package/src/compat/cache/modern-handler.ts +148 -126
- package/src/compat/cache/resume-data-cache.ts +47 -45
- package/src/compat/cache/revalidate.ts +233 -232
- package/src/compat/cache/runtime-error.ts +35 -35
- package/src/compat/cache/use-cache-transform.ts +442 -417
- package/src/compat/cache/use-cache.ts +650 -614
- package/src/compat/cache-control.ts +140 -142
- package/src/compat/client/base-path.ts +21 -20
- package/src/compat/client/css-order.ts +18 -18
- package/src/compat/client/errors/bare-boundary.ts +11 -11
- package/src/compat/client/errors/control-flow.ts +23 -23
- package/src/compat/client/errors/error-boundary.ts +61 -61
- package/src/compat/client/errors/global-error.ts +101 -91
- package/src/compat/client/errors/install.ts +71 -72
- package/src/compat/client/errors/lazy.ts +23 -23
- package/src/compat/client/errors/primitive-throw.ts +47 -45
- package/src/compat/client/errors/soft-refresh.ts +4 -4
- package/src/compat/client/link-status.ts +33 -33
- package/src/compat/client/{nav-compat-runtime.ts → nav-runtime.ts} +20 -20
- package/src/compat/client/{nav-compat.ts → nav.ts} +12 -13
- package/src/compat/client/navigation-scroll.ts +63 -63
- package/src/compat/client/optimistic-routing.ts +93 -88
- package/src/compat/client/prefetch-cache.ts +23 -24
- package/src/compat/client/route-announcer.ts +35 -35
- package/src/compat/client/segment-cache-policy.ts +20 -20
- package/src/compat/client/segment-cache.ts +309 -315
- package/src/compat/client/segment-prefetch.ts +127 -132
- package/src/compat/client/trailing-slash.ts +5 -4
- package/src/compat/css/chunking.ts +113 -116
- package/src/compat/css/inline-css.ts +21 -21
- package/src/compat/css/lightningcss.ts +37 -38
- package/src/compat/css/modules.ts +161 -175
- package/src/compat/css/nonce.ts +7 -7
- package/src/compat/css/sass-plugin.ts +18 -21
- package/src/compat/css/sass.ts +150 -152
- package/src/compat/css/styled-jsx-runtime.ts +27 -27
- package/src/compat/css/styled-jsx.ts +21 -21
- package/src/compat/edge-runtime.ts +27 -27
- package/src/compat/{adapter → export}/build-complete.ts +72 -75
- package/src/compat/export/client.ts +29 -31
- package/src/compat/export/{index.ts → emit.ts} +111 -110
- package/src/compat/export/standalone.ts +62 -54
- package/src/compat/image-optimizer/cache.ts +51 -49
- package/src/compat/image-optimizer/detect.ts +52 -52
- package/src/compat/image-optimizer/{index.ts → optimize.ts} +189 -194
- package/src/compat/image-optimizer/source.ts +77 -80
- package/src/compat/lifecycle/after-scope.ts +26 -26
- package/src/compat/lifecycle/after.ts +48 -45
- package/src/compat/lifecycle/error-funnel.ts +98 -102
- package/src/compat/lifecycle/error-serialize.ts +30 -26
- package/src/compat/lifecycle/error-ui.ts +67 -32
- package/src/compat/lifecycle/instrumentation-client.ts +36 -38
- package/src/compat/lifecycle/instrumentation.ts +85 -85
- package/src/compat/lifecycle/node-console.ts +11 -11
- package/src/compat/lifecycle/testmode.ts +160 -132
- package/src/compat/mdx/compile.ts +60 -57
- package/src/compat/mdx/plugin.ts +11 -11
- package/src/compat/mdx/{next-mdx-stub.ts → stub.ts} +5 -5
- package/src/compat/{metadata-route-artifacts.ts → metadata-artifacts.ts} +195 -191
- package/src/compat/metadata.ts +75 -81
- package/src/compat/next/cache.ts +68 -69
- package/src/compat/next/canonical-url.ts +9 -9
- package/src/compat/next/client-cache.ts +19 -19
- package/src/compat/next/client-navigation.ts +112 -116
- package/src/compat/next/client-only.ts +1 -1
- package/src/compat/next/client-script.tsx +99 -93
- package/src/compat/next/client-server.ts +10 -10
- package/src/compat/next/config-loader.ts +176 -173
- package/src/compat/next/config.ts +7 -7
- package/src/compat/next/constants.cjs +6 -6
- package/src/compat/next/constants.ts +6 -6
- package/src/compat/next/custom-server.ts +26 -24
- package/src/compat/next/dist/client/components/app-router-headers.ts +21 -21
- package/src/compat/next/dist/server/app-render/work-unit-async-storage.external.cjs +3 -4
- package/src/compat/next/dist/server/web/spec-extension/revalidate.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-cache.ts +1 -1
- package/src/compat/next/dist/server/web/spec-extension/unstable-no-store.ts +1 -1
- package/src/compat/next/dynamic.tsx +21 -18
- package/src/compat/next/error.tsx +52 -52
- package/src/compat/next/font/cache.ts +74 -74
- package/src/compat/next/font/google.ts +2 -2
- package/src/compat/next/font/index.ts +1 -1
- package/src/compat/next/font/local.ts +3 -3
- package/src/compat/next/font/runtime-client.ts +17 -15
- package/src/compat/next/font/runtime.ts +443 -408
- package/src/compat/next/font/shared.ts +120 -108
- package/src/compat/next/form.tsx +63 -63
- package/src/compat/next/head.tsx +2 -2
- package/src/compat/next/headers.ts +103 -95
- package/src/compat/next/image/client.tsx +220 -0
- package/src/compat/next/image/config.ts +56 -58
- package/src/compat/next/image/optimizer.ts +40 -36
- package/src/compat/next/image/patterns.ts +37 -40
- package/src/compat/next/{image-props.ts → image/props.ts} +208 -202
- package/src/compat/next/image/shared.ts +65 -57
- package/src/compat/next/image/static-metadata.ts +98 -107
- package/src/compat/next/image/validate.ts +79 -88
- package/src/compat/next/image.tsx +19 -23
- package/src/compat/next/index.ts +1 -1
- package/src/compat/next/legacy-image.tsx +59 -60
- package/src/compat/next/{link-validation-transform.ts → link-transform.ts} +95 -96
- package/src/compat/next/link.tsx +158 -158
- package/src/compat/next/navigation.cjs +12 -3
- package/src/compat/next/navigation.ts +48 -50
- package/src/compat/next/offline.ts +27 -27
- package/src/compat/next/og.ts +121 -124
- package/src/compat/next/preferred-region.ts +13 -14
- package/src/compat/next/redirects.ts +58 -56
- package/src/compat/next/resource-hints.ts +73 -76
- package/src/compat/next/rewrites.ts +130 -133
- package/src/compat/next/root-params.ts +45 -45
- package/src/compat/next/{optimistic-route-state.ts → route-state.ts} +52 -52
- package/src/compat/next/router.cjs +4 -2
- package/src/compat/next/router.ts +58 -61
- package/src/compat/next/script.tsx +108 -108
- package/src/compat/next/server-only.ts +1 -1
- package/src/compat/next/server.ts +19 -19
- package/src/compat/next/svgr.ts +18 -17
- package/src/compat/next/telemetry.ts +24 -24
- package/src/compat/next/{image-usage.ts → usage.ts} +70 -39
- package/src/compat/next/user-agent.ts +53 -49
- package/src/compat/next/web-vitals.ts +22 -24
- package/src/compat/otel/api.ts +41 -41
- package/src/compat/otel/client-trace-metadata.ts +25 -27
- package/src/compat/otel/fetch-span.ts +29 -29
- package/src/compat/otel/tracer.ts +331 -331
- package/src/compat/pages/api.ts +456 -0
- package/src/compat/pages/client-plugin.ts +36 -36
- package/src/compat/pages/router-state.ts +34 -34
- package/src/compat/pages/{index.ts → router.ts} +130 -135
- package/src/compat/ppr/io.ts +12 -12
- package/src/compat/ppr/missing-root-params.ts +34 -38
- package/src/compat/ppr/root-params-scan.ts +66 -66
- package/src/compat/ppr/root-params-transform.ts +24 -26
- package/src/compat/ppr/root-params.ts +30 -30
- package/src/compat/ppr/segment-config-incompat.ts +6 -7
- package/src/compat/protocol.ts +71 -70
- package/src/compat/react/action-state.ts +47 -48
- package/src/compat/react/client-lite.ts +15 -15
- package/src/compat/react/client.ts +4 -4
- package/src/compat/react/compiler-runtime.ts +11 -11
- package/src/compat/react/dom-client.ts +44 -44
- package/src/compat/react/dom-react-server.ts +10 -16
- package/src/compat/react/dom-server.ts +10 -10
- package/src/compat/react/dom.ts +52 -52
- package/src/compat/react/hooks-extra.ts +34 -35
- package/src/compat/react/parity.ts +64 -61
- package/src/compat/react/preact.ts +81 -82
- package/src/compat/react/react-server.ts +28 -28
- package/src/compat/react/router-shim.ts +1 -1
- package/src/compat/react/server-component-use.ts +8 -8
- package/src/compat/react/server-inserted-html.ts +30 -31
- package/src/compat/react/server.ts +53 -55
- package/src/compat/react/use.ts +32 -32
- package/src/compat/react/view-transition.ts +20 -20
- package/src/compat/register/actions.ts +35 -824
- package/src/compat/register/boot.ts +41 -41
- package/src/compat/register/build-tier.ts +5 -5
- package/src/compat/register/build.ts +74 -70
- package/src/compat/register/bundler.ts +161 -156
- package/src/compat/register/cache.ts +20 -20
- package/src/compat/register/client-errors.ts +3 -3
- package/src/compat/register/config.ts +6 -6
- package/src/compat/register/css-extras.ts +30 -34
- package/src/compat/register/edge-runtime.ts +3 -3
- package/src/compat/register/errors.ts +10 -12
- package/src/compat/register/export.ts +16 -16
- package/src/compat/register/font.ts +11 -11
- package/src/compat/register/hooks.ts +2 -2
- package/src/compat/register/image.ts +40 -40
- package/src/compat/register/index.ts +59 -62
- package/src/compat/register/instrumentation-client.ts +10 -10
- package/src/compat/register/lifecycle.ts +25 -28
- package/src/compat/register/mdx.ts +10 -10
- package/src/compat/register/middleware.ts +226 -16
- package/src/compat/register/otel.ts +80 -88
- package/src/compat/register/pages-api.ts +10 -463
- package/src/compat/register/ppr.ts +16 -16
- package/src/compat/register/protocol.ts +17 -18
- package/src/compat/register/proxy.ts +49 -51
- package/src/compat/register/render.ts +79 -76
- package/src/compat/register/routing.ts +162 -159
- package/src/compat/register/segment.ts +24 -1897
- package/src/compat/register/static-image.ts +3 -3
- package/src/compat/register/{misc.ts → taint.ts} +9 -9
- package/src/compat/register/typed-routes.ts +14 -14
- package/src/compat/register/{usecache.ts → use-cache.ts} +39 -39
- package/src/compat/register/validation.ts +18 -18
- package/src/compat/segment/loading-boundary.ts +43 -45
- package/src/compat/segment/page-slot.ts +69 -69
- package/src/compat/segment/serve.ts +1884 -0
- package/src/compat/segment/tree.ts +113 -112
- package/src/compat/segment/vary-key.ts +38 -38
- package/src/compat/segment/vary-params.ts +138 -142
- package/src/compat/static-params.ts +14 -12
- package/src/compat/tsconfig-defaults.ts +87 -91
- package/src/compat/typecheck/{index.ts → check.ts} +234 -212
- package/src/compat/typecheck/worker.ts +15 -12
- package/src/compat/typed-routes/{index.ts → generate.ts} +36 -36
- package/src/compat/typed-routes/manifest.ts +174 -170
- package/src/compat/typed-routes/typegen.ts +127 -110
- package/src/compat/validation/errors.ts +16 -19
- package/src/compat/validation/prerender-diagnostics.ts +521 -504
- package/src/compat/validation/{index.ts → validate.ts} +647 -648
- package/src/compat-bootstrap.ts +16 -16
- package/src/config.ts +69 -69
- package/src/css/build.ts +230 -227
- package/src/css/postcss.ts +79 -80
- package/src/css/worker.ts +14 -15
- package/src/dev/client-actions.ts +10 -10
- package/src/dev/client-chunk-store.ts +27 -27
- package/src/dev/{client-key-cache.ts → restart/client-key.ts} +76 -76
- package/src/dev/{restart-cache.ts → restart/enabled.ts} +1 -1
- package/src/dev/{global-css-cache.ts → restart/global-css.ts} +91 -83
- package/src/dev/{node-module-bundle-cache.ts → restart/node-modules.ts} +24 -24
- package/src/dev/{route-bundle-key-cache.ts → restart/route-bundle-key.ts} +53 -53
- package/src/dev/{route-facts-cache.ts → restart/route-facts.ts} +82 -82
- package/src/dev/server.ts +804 -820
- package/src/env.ts +46 -43
- package/src/extensions.ts +491 -478
- package/src/index.ts +8 -8
- package/src/internal.ts +20 -23
- package/src/{islands → render}/boundary-error.ts +3 -3
- package/src/render/hooks.ts +71 -71
- package/src/render/island-context.ts +14 -14
- package/src/render/metadata.ts +310 -310
- package/src/{ppr-postpone.ts → render/postpone.ts} +5 -5
- package/src/{ppr.ts → render/ppr.ts} +244 -245
- package/src/render/renderer.ts +2076 -2082
- package/src/render/resource-hints.ts +16 -17
- package/src/render/slots.tsx +224 -235
- package/src/{islands → render}/static-children.ts +9 -12
- package/src/{islands → render}/static-slots.ts +37 -37
- package/src/{cache/context.ts → request/cache.ts} +20 -20
- package/src/request/context.ts +107 -107
- package/src/{dynamic/source.ts → resolve/dynamic.ts} +139 -139
- package/src/resolve/engine.ts +90 -77
- package/src/resolve/imports.ts +475 -463
- package/src/resolve/scan-facts.ts +318 -296
- package/src/resolve/source-text.ts +37 -37
- package/src/{dynamic → resolve}/tree-shake.ts +132 -128
- package/src/routing/forwarded.ts +19 -19
- package/src/routing/handler.ts +84 -91
- package/src/routing/href.ts +69 -70
- package/src/routing/{metadata.ts → metadata-files.ts} +403 -401
- package/src/{proxy.ts → routing/proxy.ts} +306 -312
- package/src/routing/{request-runtime.ts → request-environment.ts} +10 -10
- package/src/routing/routes.ts +827 -815
- package/src/routing/slots.ts +164 -160
- package/src/runtime/loader.ts +952 -0
- package/src/{dev → runtime}/module-cache.ts +309 -287
- package/src/{dev → runtime}/module-generations.ts +9 -9
- package/src/{dev → runtime}/module-transform.ts +81 -72
- package/src/{dev/imports.ts → runtime/modules.ts} +934 -847
- package/src/runtime/{server.ts → vendor-build.ts} +848 -1696
- package/src/runtime/vendor.ts +425 -404
- package/src/styles.d.ts +9 -0
- package/src/types.ts +320 -335
- package/src/utils/ansi.ts +5 -5
- package/src/utils/{source.ts → code.ts} +15 -12
- package/src/utils/content-type.ts +3 -3
- package/src/utils/decode.ts +2 -2
- package/src/utils/dev-profile.ts +13 -13
- package/src/utils/error-log.ts +6 -6
- package/src/utils/esbuild.ts +18 -18
- package/src/utils/fs-cache.ts +13 -13
- package/src/utils/fs.ts +57 -49
- package/src/utils/html.ts +20 -24
- package/src/utils/native-require.ts +8 -8
- package/src/utils/serialize.ts +139 -146
- package/src/utils/verbose.ts +18 -18
- package/src/cli/analyze-print.ts +0 -181
- package/src/compat/middleware/manifest.ts +0 -210
- package/src/compat/next/image-client.tsx +0 -215
- package/src/compat/next/link-usage.ts +0 -29
- package/src/css/index.ts +0 -2
- package/src/render/index.ts +0 -1
- package/src/style-modules.d.ts +0 -9
|
@@ -8,23 +8,23 @@
|
|
|
8
8
|
// Dedupe: the same request may surface an error at both the render site and the top-level catch, so a
|
|
9
9
|
// per-work-unit flag ensures the user hook fires exactly once.
|
|
10
10
|
|
|
11
|
-
import { getWorkUnit } from '../../request/context'
|
|
12
|
-
import { getRequestRuntime } from '../../routing/request-
|
|
13
|
-
import { selectRouteForRequest } from '../../routing/routes'
|
|
14
|
-
import path from 'node:path'
|
|
15
|
-
import type { RouteManifestEntry } from '../../types'
|
|
16
|
-
import type { RequestErrorContext, RequestErrorInfo } from '../../extensions'
|
|
11
|
+
import { getWorkUnit } from '../../request/context'
|
|
12
|
+
import { getRequestRuntime } from '../../routing/request-environment'
|
|
13
|
+
import { selectRouteForRequest } from '../../routing/routes'
|
|
14
|
+
import path from 'node:path'
|
|
15
|
+
import type { RouteManifestEntry } from '../../types'
|
|
16
|
+
import type { RequestErrorContext, RequestErrorInfo } from '../../extensions'
|
|
17
17
|
import {
|
|
18
18
|
isForbiddenError,
|
|
19
19
|
isNotFoundError,
|
|
20
20
|
isRedirectError,
|
|
21
21
|
isUnauthorizedError,
|
|
22
|
-
} from '../../api/navigation'
|
|
23
|
-
import { isPostpone } from '../../ppr'
|
|
24
|
-
import { markErrorLogged } from '../../utils/error-log'
|
|
25
|
-
import { getUserOnRequestError, instrumentationReady } from './instrumentation'
|
|
22
|
+
} from '../../api/navigation'
|
|
23
|
+
import { isPostpone } from '../../render/ppr'
|
|
24
|
+
import { markErrorLogged } from '../../utils/error-log'
|
|
25
|
+
import { getUserOnRequestError, instrumentationReady } from './instrumentation'
|
|
26
26
|
|
|
27
|
-
const ERROR_REPORTED_KEY = Symbol.for('pnext.errorReported')
|
|
27
|
+
const ERROR_REPORTED_KEY = Symbol.for('pnext.errorReported')
|
|
28
28
|
|
|
29
29
|
/** True for Next control-flow errors that must NOT be reported to the hook. */
|
|
30
30
|
function isControlFlowError(error: unknown): boolean {
|
|
@@ -35,16 +35,16 @@ function isControlFlowError(error: unknown): boolean {
|
|
|
35
35
|
isUnauthorizedError(error) ||
|
|
36
36
|
isPostpone(error) ||
|
|
37
37
|
isNextDynamicNoSsr(error)
|
|
38
|
-
)
|
|
38
|
+
)
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/** next/dynamic ssr:false bailout digest (skip-next-internal-error asserts skip). */
|
|
42
42
|
function isNextDynamicNoSsr(error: unknown): boolean {
|
|
43
|
-
const digest = (error as { digest?: unknown } | null | undefined)?.digest
|
|
43
|
+
const digest = (error as { digest?: unknown } | null | undefined)?.digest
|
|
44
44
|
return (
|
|
45
45
|
digest === 'NEXT_DYNAMIC_NO_SSR_CODE' ||
|
|
46
46
|
(typeof digest === 'string' && digest.startsWith('DYNAMIC_SERVER_USAGE'))
|
|
47
|
-
)
|
|
47
|
+
)
|
|
48
48
|
}
|
|
49
49
|
|
|
50
50
|
/**
|
|
@@ -53,15 +53,13 @@ function isNextDynamicNoSsr(error: unknown): boolean {
|
|
|
53
53
|
* onRequestError `routePath` field reports. Mirrors pnext-cli's toNextRoute.
|
|
54
54
|
*/
|
|
55
55
|
function toDisplayRoute(route: RouteManifestEntry): string {
|
|
56
|
-
let value = route.route || '/'
|
|
56
|
+
let value = route.route || '/'
|
|
57
57
|
if (route.catchAll) {
|
|
58
|
-
const pattern = route.catchAllOptional
|
|
59
|
-
|
|
60
|
-
: `[...${route.catchAll}]`;
|
|
61
|
-
value = value.replace(`:${route.catchAll}*`, pattern);
|
|
58
|
+
const pattern = route.catchAllOptional ? `[[...${route.catchAll}]]` : `[...${route.catchAll}]`
|
|
59
|
+
value = value.replace(`:${route.catchAll}*`, pattern)
|
|
62
60
|
}
|
|
63
|
-
for (const param of route.params) value = value.replace(`:${param}`, `[${param}]`)
|
|
64
|
-
return value
|
|
61
|
+
for (const param of route.params) value = value.replace(`:${param}`, `[${param}]`)
|
|
62
|
+
return value
|
|
65
63
|
}
|
|
66
64
|
|
|
67
65
|
/** Return `Pages Router` when route files live under pages/, otherwise `App Router`. */
|
|
@@ -70,30 +68,30 @@ function routeKindFromFile(
|
|
|
70
68
|
route: RouteManifestEntry,
|
|
71
69
|
): 'Pages Router' | 'App Router' {
|
|
72
70
|
if (!runtimeRoot) {
|
|
73
|
-
return 'App Router'
|
|
71
|
+
return 'App Router'
|
|
74
72
|
}
|
|
75
|
-
const normalized = path.normalize(route.file)
|
|
76
|
-
const pagesRoot = path.join(runtimeRoot, 'pages')
|
|
77
|
-
const appRoot = path.join(runtimeRoot, 'app')
|
|
73
|
+
const normalized = path.normalize(route.file)
|
|
74
|
+
const pagesRoot = path.join(runtimeRoot, 'pages')
|
|
75
|
+
const appRoot = path.join(runtimeRoot, 'app')
|
|
78
76
|
return normalized.startsWith(pagesRoot + path.sep) || normalized === pagesRoot
|
|
79
77
|
? 'Pages Router'
|
|
80
78
|
: normalized.startsWith(appRoot + path.sep) || normalized === appRoot
|
|
81
79
|
? 'App Router'
|
|
82
|
-
: 'App Router'
|
|
80
|
+
: 'App Router'
|
|
83
81
|
}
|
|
84
82
|
|
|
85
83
|
interface RouteMatch {
|
|
86
|
-
route: RouteManifestEntry
|
|
87
|
-
routePath: string
|
|
84
|
+
route: RouteManifestEntry
|
|
85
|
+
routePath: string
|
|
88
86
|
}
|
|
89
87
|
|
|
90
88
|
function resolveRoute(pathname: string): RouteMatch | undefined {
|
|
91
|
-
const runtime = getRequestRuntime()
|
|
92
|
-
if (!runtime) return undefined
|
|
93
|
-
const selectedPath = pathname.split('?')[0] ?? pathname
|
|
94
|
-
const matched = selectRouteForRequest(runtime.routes, selectedPath, undefined)
|
|
95
|
-
if (!matched) return undefined
|
|
96
|
-
return { route: matched.route, routePath: toDisplayRoute(matched.route) }
|
|
89
|
+
const runtime = getRequestRuntime()
|
|
90
|
+
if (!runtime) return undefined
|
|
91
|
+
const selectedPath = pathname.split('?')[0] ?? pathname
|
|
92
|
+
const matched = selectRouteForRequest(runtime.routes, selectedPath, undefined)
|
|
93
|
+
if (!matched) return undefined
|
|
94
|
+
return { route: matched.route, routePath: toDisplayRoute(matched.route) }
|
|
97
95
|
}
|
|
98
96
|
|
|
99
97
|
/**
|
|
@@ -103,9 +101,9 @@ function resolveRoute(pathname: string): RouteMatch | undefined {
|
|
|
103
101
|
*/
|
|
104
102
|
function resolveRoutePath(path: string): string | undefined {
|
|
105
103
|
try {
|
|
106
|
-
return resolveRoute(path)?.routePath
|
|
104
|
+
return resolveRoute(path)?.routePath
|
|
107
105
|
} catch {
|
|
108
|
-
return undefined
|
|
106
|
+
return undefined
|
|
109
107
|
}
|
|
110
108
|
}
|
|
111
109
|
|
|
@@ -118,8 +116,8 @@ function resolveRoutePath(path: string): string | undefined {
|
|
|
118
116
|
* core reports an ISR revalidation error.
|
|
119
117
|
*/
|
|
120
118
|
function errorDigest(error: unknown): string | undefined {
|
|
121
|
-
const digest = (error as { digest?: unknown } | null | undefined)?.digest
|
|
122
|
-
return typeof digest === 'string' ? digest : undefined
|
|
119
|
+
const digest = (error as { digest?: unknown } | null | undefined)?.digest
|
|
120
|
+
return typeof digest === 'string' ? digest : undefined
|
|
123
121
|
}
|
|
124
122
|
|
|
125
123
|
function buildContext(
|
|
@@ -127,24 +125,22 @@ function buildContext(
|
|
|
127
125
|
context: RequestErrorContext,
|
|
128
126
|
path: string,
|
|
129
127
|
): Record<string, unknown> {
|
|
130
|
-
const runtime = getRequestRuntime()
|
|
131
|
-
const match = runtime ? resolveRoute(path) : undefined
|
|
132
|
-
const out: Record<string, unknown> = {}
|
|
133
|
-
out.routerKind = match
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
out.
|
|
137
|
-
const routePath = match ? match.routePath : resolveRoutePath(path);
|
|
138
|
-
if (routePath) out.routePath = routePath;
|
|
128
|
+
const runtime = getRequestRuntime()
|
|
129
|
+
const match = runtime ? resolveRoute(path) : undefined
|
|
130
|
+
const out: Record<string, unknown> = {}
|
|
131
|
+
out.routerKind = match ? routeKindFromFile(runtime?.config.root, match.route) : 'App Router'
|
|
132
|
+
out.routeType = context.routeKind === 'route-handler' ? 'route' : 'render'
|
|
133
|
+
const routePath = match ? match.routePath : resolveRoutePath(path)
|
|
134
|
+
if (routePath) out.routePath = routePath
|
|
139
135
|
if (context.routeKind === 'html') {
|
|
140
136
|
out.renderSource =
|
|
141
|
-
(context as { renderSource?: string }).renderSource ?? 'react-server-components'
|
|
137
|
+
(context as { renderSource?: string }).renderSource ?? 'react-server-components'
|
|
142
138
|
}
|
|
143
|
-
const revalidateReason = (context as { revalidateReason?: string }).revalidateReason
|
|
144
|
-
if (revalidateReason) out.revalidateReason = revalidateReason
|
|
145
|
-
const digest = errorDigest(error)
|
|
146
|
-
if (digest) out.digest = digest
|
|
147
|
-
return out
|
|
139
|
+
const revalidateReason = (context as { revalidateReason?: string }).revalidateReason
|
|
140
|
+
if (revalidateReason) out.revalidateReason = revalidateReason
|
|
141
|
+
const digest = errorDigest(error)
|
|
142
|
+
if (digest) out.digest = digest
|
|
143
|
+
return out
|
|
148
144
|
}
|
|
149
145
|
|
|
150
146
|
/**
|
|
@@ -154,25 +150,25 @@ function buildContext(
|
|
|
154
150
|
* context the endpoint would (routeType 'action', RSC-payload source) or the suite sees a render context.
|
|
155
151
|
*/
|
|
156
152
|
function buildActionContext(error: unknown, path: string): Record<string, unknown> {
|
|
157
|
-
const runtime = getRequestRuntime()
|
|
158
|
-
const match = runtime ? resolveRoute(path) : undefined
|
|
153
|
+
const runtime = getRequestRuntime()
|
|
154
|
+
const match = runtime ? resolveRoute(path) : undefined
|
|
159
155
|
const out: Record<string, unknown> = {
|
|
160
156
|
routerKind: match ? routeKindFromFile(runtime?.config.root, match.route) : 'App Router',
|
|
161
157
|
routeType: 'action',
|
|
162
158
|
renderSource: 'react-server-components-payload',
|
|
163
|
-
}
|
|
164
|
-
const routePath = match ? match.routePath : resolveRoutePath(path)
|
|
165
|
-
if (routePath) out.routePath = routePath
|
|
166
|
-
const digest = errorDigest(error)
|
|
167
|
-
if (digest) out.digest = digest
|
|
168
|
-
return out
|
|
159
|
+
}
|
|
160
|
+
const routePath = match ? match.routePath : resolveRoutePath(path)
|
|
161
|
+
if (routePath) out.routePath = routePath
|
|
162
|
+
const digest = errorDigest(error)
|
|
163
|
+
if (digest) out.digest = digest
|
|
164
|
+
return out
|
|
169
165
|
}
|
|
170
166
|
|
|
171
167
|
/** True when the failing request is a server-action invocation (JS/form dispatch). */
|
|
172
168
|
function isServerActionRequest(headers: Headers): boolean {
|
|
173
|
-
if (headers.has('next-action')) return true
|
|
174
|
-
const accept = headers.get('accept') ?? ''
|
|
175
|
-
return accept.includes('text/x-component')
|
|
169
|
+
if (headers.has('next-action')) return true
|
|
170
|
+
const accept = headers.get('accept') ?? ''
|
|
171
|
+
return accept.includes('text/x-component')
|
|
176
172
|
}
|
|
177
173
|
|
|
178
174
|
/**
|
|
@@ -184,23 +180,23 @@ function isServerActionRequest(headers: Headers): boolean {
|
|
|
184
180
|
* (redirect()/notFound()) and never throws.
|
|
185
181
|
*/
|
|
186
182
|
export async function reportActionErrorToUser(error: unknown, request: Request): Promise<void> {
|
|
187
|
-
if (isControlFlowError(error)) return
|
|
183
|
+
if (isControlFlowError(error)) return
|
|
188
184
|
|
|
189
|
-
const unit = getWorkUnit()
|
|
185
|
+
const unit = getWorkUnit()
|
|
190
186
|
if (unit) {
|
|
191
|
-
const bag = (unit.compat ??= {})
|
|
192
|
-
if (bag[ERROR_REPORTED_KEY]) return
|
|
193
|
-
bag[ERROR_REPORTED_KEY] = true
|
|
187
|
+
const bag = (unit.compat ??= {})
|
|
188
|
+
if (bag[ERROR_REPORTED_KEY]) return
|
|
189
|
+
bag[ERROR_REPORTED_KEY] = true
|
|
194
190
|
}
|
|
195
191
|
|
|
196
|
-
await instrumentationReady()
|
|
197
|
-
const hook = getUserOnRequestError()
|
|
198
|
-
if (!hook) return
|
|
192
|
+
await instrumentationReady()
|
|
193
|
+
const hook = getUserOnRequestError()
|
|
194
|
+
if (!hook) return
|
|
199
195
|
|
|
200
|
-
let path = request.url
|
|
196
|
+
let path = request.url
|
|
201
197
|
try {
|
|
202
|
-
const parsed = new URL(request.url)
|
|
203
|
-
path = parsed.pathname + parsed.search
|
|
198
|
+
const parsed = new URL(request.url)
|
|
199
|
+
path = parsed.pathname + parsed.search
|
|
204
200
|
} catch {
|
|
205
201
|
// request.url is already a path.
|
|
206
202
|
}
|
|
@@ -210,18 +206,18 @@ export async function reportActionErrorToUser(error: unknown, request: Request):
|
|
|
210
206
|
error,
|
|
211
207
|
{ path, method: request.method, headers: headersToObject(request.headers) },
|
|
212
208
|
buildActionContext(error, path),
|
|
213
|
-
)
|
|
209
|
+
)
|
|
214
210
|
} catch (hookError) {
|
|
215
|
-
console.error('instrumentation onRequestError failed:', hookError)
|
|
211
|
+
console.error('instrumentation onRequestError failed:', hookError)
|
|
216
212
|
}
|
|
217
213
|
}
|
|
218
214
|
|
|
219
215
|
function headersToObject(headers: Headers): Record<string, string> {
|
|
220
|
-
const out: Record<string, string> = {}
|
|
216
|
+
const out: Record<string, string> = {}
|
|
221
217
|
headers.forEach((value, key) => {
|
|
222
|
-
out[key] = value
|
|
223
|
-
})
|
|
224
|
-
return out
|
|
218
|
+
out[key] = value
|
|
219
|
+
})
|
|
220
|
+
return out
|
|
225
221
|
}
|
|
226
222
|
|
|
227
223
|
/**
|
|
@@ -233,24 +229,24 @@ export async function reportRequestErrorToUser(
|
|
|
233
229
|
requestInfo: RequestErrorInfo,
|
|
234
230
|
context: RequestErrorContext,
|
|
235
231
|
): Promise<void> {
|
|
236
|
-
if (isControlFlowError(error)) return
|
|
232
|
+
if (isControlFlowError(error)) return
|
|
237
233
|
|
|
238
|
-
const unit = getWorkUnit()
|
|
234
|
+
const unit = getWorkUnit()
|
|
239
235
|
if (unit) {
|
|
240
|
-
const bag = (unit.compat ??= {})
|
|
241
|
-
if (bag[ERROR_REPORTED_KEY]) return
|
|
242
|
-
bag[ERROR_REPORTED_KEY] = true
|
|
236
|
+
const bag = (unit.compat ??= {})
|
|
237
|
+
if (bag[ERROR_REPORTED_KEY]) return
|
|
238
|
+
bag[ERROR_REPORTED_KEY] = true
|
|
243
239
|
}
|
|
244
240
|
|
|
245
|
-
await instrumentationReady()
|
|
246
|
-
const hook = getUserOnRequestError()
|
|
247
|
-
if (!hook) return
|
|
241
|
+
await instrumentationReady()
|
|
242
|
+
const hook = getUserOnRequestError()
|
|
243
|
+
if (!hook) return
|
|
248
244
|
|
|
249
245
|
// `path` is the original URL incl. search (dynamic-routes asserts search present).
|
|
250
|
-
let path = requestInfo.url
|
|
246
|
+
let path = requestInfo.url
|
|
251
247
|
try {
|
|
252
|
-
const parsed = new URL(requestInfo.url)
|
|
253
|
-
path = parsed.pathname + parsed.search
|
|
248
|
+
const parsed = new URL(requestInfo.url)
|
|
249
|
+
path = parsed.pathname + parsed.search
|
|
254
250
|
} catch {
|
|
255
251
|
// requestInfo.url is already a path.
|
|
256
252
|
}
|
|
@@ -260,20 +256,20 @@ export async function reportRequestErrorToUser(
|
|
|
260
256
|
// the action context so it matches what the endpoint would have reported.
|
|
261
257
|
const hookContext = isServerActionRequest(requestInfo.headers)
|
|
262
258
|
? buildActionContext(error, path)
|
|
263
|
-
: buildContext(error, context, path)
|
|
259
|
+
: buildContext(error, context, path)
|
|
264
260
|
|
|
265
261
|
try {
|
|
266
262
|
await hook(
|
|
267
263
|
error,
|
|
268
264
|
{ path, method: requestInfo.method, headers: headersToObject(requestInfo.headers) },
|
|
269
265
|
hookContext,
|
|
270
|
-
)
|
|
266
|
+
)
|
|
271
267
|
} catch (hookError) {
|
|
272
|
-
console.error('instrumentation onRequestError failed:', hookError)
|
|
268
|
+
console.error('instrumentation onRequestError failed:', hookError)
|
|
273
269
|
}
|
|
274
270
|
}
|
|
275
271
|
|
|
276
|
-
let guardInstalled = false
|
|
272
|
+
let guardInstalled = false
|
|
277
273
|
|
|
278
274
|
/**
|
|
279
275
|
* Server-lifecycle safety net for SSR errors that escape as unhandled promise rejections instead of
|
|
@@ -296,11 +292,11 @@ let guardInstalled = false;
|
|
|
296
292
|
* throw at the SSR site and route it through reportRequestError; this net only guarantees survival.
|
|
297
293
|
*/
|
|
298
294
|
export function installUnhandledRejectionGuard(): void {
|
|
299
|
-
if (guardInstalled) return
|
|
300
|
-
if (typeof process === 'undefined' || typeof process.on !== 'function') return
|
|
301
|
-
guardInstalled = true
|
|
295
|
+
if (guardInstalled) return
|
|
296
|
+
if (typeof process === 'undefined' || typeof process.on !== 'function') return
|
|
297
|
+
guardInstalled = true
|
|
302
298
|
process.on('unhandledRejection', (reason: unknown) => {
|
|
303
|
-
if (isControlFlowError(reason)) return
|
|
304
|
-
if (markErrorLogged(reason)) console.error(reason)
|
|
305
|
-
})
|
|
299
|
+
if (isControlFlowError(reason)) return
|
|
300
|
+
if (markErrorLogged(reason)) console.error(reason)
|
|
301
|
+
})
|
|
306
302
|
}
|
|
@@ -11,36 +11,40 @@
|
|
|
11
11
|
// NOTE: this function must NOT log the error to the server console. Core's renderer already logs the
|
|
12
12
|
// render error exactly once right before it calls serializeError(); logging here too double-prints it.
|
|
13
13
|
|
|
14
|
-
import type { SerializeErrorContext, SerializedError } from '../../extensions'
|
|
15
|
-
import {
|
|
14
|
+
import type { SerializeErrorContext, SerializedError } from '../../extensions'
|
|
15
|
+
import {
|
|
16
|
+
isTaggedPrimitiveThrow,
|
|
17
|
+
tagPrimitiveThrow,
|
|
18
|
+
untagPrimitiveThrow,
|
|
19
|
+
} from '../client/errors/primitive-throw'
|
|
16
20
|
|
|
17
21
|
// React's production redaction text for RSC render errors (#441). Boundary
|
|
18
22
|
// suites assert this verbatim in prod.
|
|
19
23
|
const REDACTED_MESSAGE =
|
|
20
|
-
'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.'
|
|
24
|
+
'Minified React error #441; visit https://react.dev/errors/441 for the full message or use the non-minified dev environment for full errors and additional helpful warnings.'
|
|
21
25
|
|
|
22
26
|
// Next uses next/dist/compiled/string-hash; any stable non-negative hash whose
|
|
23
27
|
// decimal string matches /\w+/ satisfies the compat assertions.
|
|
24
28
|
function stableDigest(input: string): string {
|
|
25
|
-
let hash = 5381
|
|
29
|
+
let hash = 5381
|
|
26
30
|
for (let i = 0; i < input.length; i++) {
|
|
27
|
-
hash = (hash * 33) ^ input.charCodeAt(i)
|
|
31
|
+
hash = (hash * 33) ^ input.charCodeAt(i)
|
|
28
32
|
}
|
|
29
|
-
return (hash >>> 0).toString()
|
|
33
|
+
return (hash >>> 0).toString()
|
|
30
34
|
}
|
|
31
35
|
|
|
32
36
|
function customDigest(error: Error): string | undefined {
|
|
33
|
-
const digest = (error as { digest?: unknown }).digest
|
|
34
|
-
return typeof digest === 'string' && digest.length > 0 ? digest : undefined
|
|
37
|
+
const digest = (error as { digest?: unknown }).digest
|
|
38
|
+
return typeof digest === 'string' && digest.length > 0 ? digest : undefined
|
|
35
39
|
}
|
|
36
40
|
|
|
37
41
|
// Next appends an error-code suffix to the hash digest when the thrown value
|
|
38
42
|
// was not an Error: prod RSC wraps a nullish throw and reports `@E394`
|
|
39
43
|
// (test/e2e/app-dir/errors asserts `digest: '<hash>@E394'` in the prod log).
|
|
40
44
|
function digestSuffix(error: Error): string {
|
|
41
|
-
if (!isTaggedPrimitiveThrow(error)) return ''
|
|
42
|
-
const raw = untagPrimitiveThrow(error)
|
|
43
|
-
return raw === null || raw === undefined ? '@E394' : ''
|
|
45
|
+
if (!isTaggedPrimitiveThrow(error)) return ''
|
|
46
|
+
const raw = untagPrimitiveThrow(error)
|
|
47
|
+
return raw === null || raw === undefined ? '@E394' : ''
|
|
44
48
|
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
@@ -49,9 +53,9 @@ function digestSuffix(error: Error): string {
|
|
|
49
53
|
* snapshot asserts, and the raw value tagged so the digest picks up the nullish suffix.
|
|
50
54
|
*/
|
|
51
55
|
export function wrapThrownValue(value: unknown): Error {
|
|
52
|
-
const error = tagPrimitiveThrow(value)
|
|
53
|
-
error.stack = `Error: ${error.message}\n at stringify (<anonymous>)
|
|
54
|
-
return error
|
|
56
|
+
const error = tagPrimitiveThrow(value)
|
|
57
|
+
error.stack = `Error: ${error.message}\n at stringify (<anonymous>)`
|
|
58
|
+
return error
|
|
55
59
|
}
|
|
56
60
|
|
|
57
61
|
/**
|
|
@@ -62,26 +66,26 @@ export function wrapThrownValue(value: unknown): Error {
|
|
|
62
66
|
export function formatErrorLog(trace: string, digest: string, error?: Error): string {
|
|
63
67
|
// An error funneled out of a 'use cache' scope carries Next's environment tag;
|
|
64
68
|
// util.inspect prints it before the digest, so the log must too.
|
|
65
|
-
const environmentName = (error as { environmentName?: unknown } | undefined)?.environmentName
|
|
69
|
+
const environmentName = (error as { environmentName?: unknown } | undefined)?.environmentName
|
|
66
70
|
const environment =
|
|
67
|
-
typeof environmentName === 'string' ? ` environmentName: '${environmentName}',\n` : ''
|
|
68
|
-
return `⨯ ${trace} {\n${environment} digest: '${digest}'\n}
|
|
71
|
+
typeof environmentName === 'string' ? ` environmentName: '${environmentName}',\n` : ''
|
|
72
|
+
return `⨯ ${trace} {\n${environment} digest: '${digest}'\n}`
|
|
69
73
|
}
|
|
70
74
|
|
|
71
75
|
export function serializeBoundaryError(ctx: SerializeErrorContext): SerializedError {
|
|
72
|
-
const { error, dev } = ctx
|
|
73
|
-
const custom = customDigest(error)
|
|
76
|
+
const { error, dev } = ctx
|
|
77
|
+
const custom = customDigest(error)
|
|
74
78
|
const digest =
|
|
75
|
-
custom ?? stableDigest(`${error.message}${error.stack ?? ''}`) + digestSuffix(error)
|
|
79
|
+
custom ?? stableDigest(`${error.message}${error.stack ?? ''}`) + digestSuffix(error)
|
|
76
80
|
|
|
77
81
|
// Boundary components render `${error}` (e.g. `Global error: ${error}`), so
|
|
78
82
|
// the prop must stringify as `Error: <message>` like React's transported
|
|
79
83
|
// error. Return a real Error carrying the (possibly redacted) message + digest.
|
|
80
84
|
const boundaryError = new Error(dev ? error.message : REDACTED_MESSAGE) as Error & {
|
|
81
|
-
digest?: string
|
|
82
|
-
}
|
|
83
|
-
boundaryError.name = error.name || 'Error'
|
|
84
|
-
boundaryError.digest = digest
|
|
85
|
-
boundaryError.stack = undefined
|
|
86
|
-
return boundaryError
|
|
85
|
+
digest?: string
|
|
86
|
+
}
|
|
87
|
+
boundaryError.name = error.name || 'Error'
|
|
88
|
+
boundaryError.digest = digest
|
|
89
|
+
boundaryError.stack = undefined
|
|
90
|
+
return boundaryError
|
|
87
91
|
}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
// these through the httpAccessFallbackUi / defaultGlobalErrorUi render extensions; a pure-core app
|
|
5
5
|
// keeps its own compact fallback.
|
|
6
6
|
|
|
7
|
-
import { h } from 'preact'
|
|
8
|
-
import type { SerializedError } from '../../extensions'
|
|
7
|
+
import { h } from 'preact'
|
|
8
|
+
import type { SerializedError } from '../../extensions'
|
|
9
9
|
|
|
10
10
|
// Next's HTTPAccessErrorFallback inline styles (access-error-styles.ts).
|
|
11
11
|
const styles = {
|
|
@@ -30,9 +30,9 @@ const styles = {
|
|
|
30
30
|
lineHeight: '49px',
|
|
31
31
|
},
|
|
32
32
|
h2: { fontSize: 14, fontWeight: 400, lineHeight: '49px', margin: 0 },
|
|
33
|
-
} as const
|
|
33
|
+
} as const
|
|
34
34
|
|
|
35
|
-
const httpFallbackCss = `body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}
|
|
35
|
+
const httpFallbackCss = `body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}`
|
|
36
36
|
|
|
37
37
|
export function httpAccessFallbackUi(status: number, message: string): unknown {
|
|
38
38
|
return h(
|
|
@@ -45,7 +45,7 @@ export function httpAccessFallbackUi(status: number, message: string): unknown {
|
|
|
45
45
|
h('h1', { className: 'next-error-h1', style: styles.h1 }, String(status)),
|
|
46
46
|
h('div', { style: styles.desc }, h('h2', { style: styles.h2 }, message)),
|
|
47
47
|
),
|
|
48
|
-
)
|
|
48
|
+
)
|
|
49
49
|
}
|
|
50
50
|
|
|
51
51
|
// Next's DefaultGlobalError (builtin/global-error.tsx + error-styles.tsx). The
|
|
@@ -80,16 +80,34 @@ const errorStyles = {
|
|
|
80
80
|
form: { margin: 0 },
|
|
81
81
|
buttonGroup: { display: 'flex', gap: '8px', alignItems: 'center' },
|
|
82
82
|
button: {
|
|
83
|
-
display: 'inline-flex',
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
83
|
+
display: 'inline-flex',
|
|
84
|
+
alignItems: 'center',
|
|
85
|
+
justifyContent: 'center',
|
|
86
|
+
height: '32px',
|
|
87
|
+
padding: '0 12px',
|
|
88
|
+
fontSize: '14px',
|
|
89
|
+
fontWeight: 500,
|
|
90
|
+
lineHeight: '20px',
|
|
91
|
+
borderRadius: '6px',
|
|
92
|
+
cursor: 'pointer',
|
|
93
|
+
color: 'var(--next-error-btn-text)',
|
|
94
|
+
background: 'var(--next-error-btn-bg)',
|
|
95
|
+
border: 'var(--next-error-btn-border)',
|
|
87
96
|
},
|
|
88
97
|
buttonSecondary: {
|
|
89
|
-
display: 'inline-flex',
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
98
|
+
display: 'inline-flex',
|
|
99
|
+
alignItems: 'center',
|
|
100
|
+
justifyContent: 'center',
|
|
101
|
+
height: '32px',
|
|
102
|
+
padding: '0 12px',
|
|
103
|
+
fontSize: '14px',
|
|
104
|
+
fontWeight: 500,
|
|
105
|
+
lineHeight: '20px',
|
|
106
|
+
borderRadius: '6px',
|
|
107
|
+
cursor: 'pointer',
|
|
108
|
+
color: 'var(--next-error-btn-secondary-text)',
|
|
109
|
+
background: 'var(--next-error-btn-secondary-bg)',
|
|
110
|
+
border: 'var(--next-error-btn-secondary-border)',
|
|
93
111
|
},
|
|
94
112
|
digestFooter: {
|
|
95
113
|
position: 'fixed',
|
|
@@ -104,16 +122,25 @@ const errorStyles = {
|
|
|
104
122
|
margin: '0',
|
|
105
123
|
color: 'var(--next-error-digest)',
|
|
106
124
|
},
|
|
107
|
-
} as const
|
|
125
|
+
} as const
|
|
108
126
|
|
|
109
|
-
const errorThemeCss =
|
|
110
|
-
`:root{--next-error-bg:#fff;--next-error-text:#171717;--next-error-title:#171717;--next-error-message:#171717;--next-error-digest:#666666;--next-error-btn-text:#fff;--next-error-btn-bg:#171717;--next-error-btn-border:none;--next-error-btn-secondary-text:#171717;--next-error-btn-secondary-bg:transparent;--next-error-btn-secondary-border:1px solid rgba(0,0,0,.08)}@media (prefers-color-scheme:dark){:root{--next-error-bg:#0a0a0a;--next-error-text:#ededed;--next-error-title:#ededed;--next-error-message:#ededed;--next-error-digest:#a0a0a0;--next-error-btn-text:#0a0a0a;--next-error-btn-bg:#ededed;--next-error-btn-border:none;--next-error-btn-secondary-text:#ededed;--next-error-btn-secondary-bg:transparent;--next-error-btn-secondary-border:1px solid rgba(255,255,255,.14)}}body{margin:0;color:var(--next-error-text);background:var(--next-error-bg);}`;
|
|
127
|
+
const errorThemeCss = `:root{--next-error-bg:#fff;--next-error-text:#171717;--next-error-title:#171717;--next-error-message:#171717;--next-error-digest:#666666;--next-error-btn-text:#fff;--next-error-btn-bg:#171717;--next-error-btn-border:none;--next-error-btn-secondary-text:#171717;--next-error-btn-secondary-bg:transparent;--next-error-btn-secondary-border:1px solid rgba(0,0,0,.08)}@media (prefers-color-scheme:dark){:root{--next-error-bg:#0a0a0a;--next-error-text:#ededed;--next-error-title:#ededed;--next-error-message:#ededed;--next-error-digest:#a0a0a0;--next-error-btn-text:#0a0a0a;--next-error-btn-bg:#ededed;--next-error-btn-border:none;--next-error-btn-secondary-text:#ededed;--next-error-btn-secondary-bg:transparent;--next-error-btn-secondary-border:1px solid rgba(255,255,255,.14)}}body{margin:0;color:var(--next-error-text);background:var(--next-error-bg);}`
|
|
111
128
|
|
|
112
129
|
function warningIcon() {
|
|
113
|
-
return h(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
130
|
+
return h(
|
|
131
|
+
'svg',
|
|
132
|
+
{
|
|
133
|
+
width: '32',
|
|
134
|
+
height: '32',
|
|
135
|
+
viewBox: '-0.2 -1.5 32 32',
|
|
136
|
+
fill: 'none',
|
|
137
|
+
style: errorStyles.icon,
|
|
138
|
+
},
|
|
139
|
+
h('path', {
|
|
140
|
+
d: 'M16.9328 0C18.0839.000116771 19.1334.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C.527541 29-.439628 27.4588.201371 26.1309L11.9973 1.69531C12.4979.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z',
|
|
141
|
+
fill: 'var(--next-error-title)',
|
|
142
|
+
}),
|
|
143
|
+
)
|
|
117
144
|
}
|
|
118
145
|
|
|
119
146
|
// The default/global-error document is served as a fully static document with no page-hydration
|
|
@@ -123,24 +150,24 @@ function warningIcon() {
|
|
|
123
150
|
// bootstrap that reports the same message/digest via `reportError` (falling back to a synthetic error
|
|
124
151
|
// event) so the client observes the same uncaught signal. Never runs in dev, where the redbox owns it.
|
|
125
152
|
export function globalErrorReportScript(error: SerializedError): string {
|
|
126
|
-
const message = JSON.stringify(error.message ?? '')
|
|
127
|
-
const digest = JSON.stringify(error.digest ?? '')
|
|
128
|
-
return `<script>(function(){try{var e=new Error(${message});if(${digest})e.digest=${digest};if(typeof reportError==='function'){reportError(e);}else{window.dispatchEvent(new ErrorEvent('error',{error:e,message:e.message}));}}catch(_){}})();</script
|
|
153
|
+
const message = JSON.stringify(error.message ?? '')
|
|
154
|
+
const digest = JSON.stringify(error.digest ?? '')
|
|
155
|
+
return `<script>(function(){try{var e=new Error(${message});if(${digest})e.digest=${digest};if(typeof reportError==='function'){reportError(e);}else{window.dispatchEvent(new ErrorEvent('error',{error:e,message:e.message}));}}catch(_){}})();</script>`
|
|
129
156
|
}
|
|
130
157
|
|
|
131
158
|
export function defaultGlobalErrorUi(error: SerializedError): unknown {
|
|
132
|
-
const digest = error.digest
|
|
133
|
-
const isServerError = Boolean(digest)
|
|
159
|
+
const digest = error.digest
|
|
160
|
+
const isServerError = Boolean(digest)
|
|
134
161
|
const message = isServerError
|
|
135
162
|
? 'A server error occurred. Reload to try again.'
|
|
136
|
-
: 'Reload to try again, or go back.'
|
|
163
|
+
: 'Reload to try again, or go back.'
|
|
137
164
|
return h(
|
|
138
165
|
'html',
|
|
139
166
|
{ id: '__next_error__' },
|
|
140
167
|
h(
|
|
141
168
|
'head',
|
|
142
169
|
null,
|
|
143
|
-
h('title', null,
|
|
170
|
+
h('title', null, '500: This page couldn’t load'),
|
|
144
171
|
h('style', { dangerouslySetInnerHTML: { __html: errorThemeCss } }),
|
|
145
172
|
),
|
|
146
173
|
h(
|
|
@@ -153,15 +180,23 @@ export function defaultGlobalErrorUi(error: SerializedError): unknown {
|
|
|
153
180
|
'div',
|
|
154
181
|
{ style: errorStyles.card },
|
|
155
182
|
warningIcon(),
|
|
156
|
-
h('h1', { style: errorStyles.title },
|
|
183
|
+
h('h1', { style: errorStyles.title }, 'This page couldn’t load'),
|
|
157
184
|
h('p', { style: errorStyles.message }, message),
|
|
158
|
-
h(
|
|
159
|
-
|
|
160
|
-
|
|
185
|
+
h(
|
|
186
|
+
'div',
|
|
187
|
+
{ style: errorStyles.buttonGroup },
|
|
188
|
+
h(
|
|
189
|
+
'form',
|
|
190
|
+
{ style: errorStyles.form },
|
|
191
|
+
h('button', { type: 'submit', style: errorStyles.button }, 'Reload'),
|
|
192
|
+
),
|
|
193
|
+
!isServerError
|
|
194
|
+
? h('button', { type: 'button', style: errorStyles.buttonSecondary }, 'Back')
|
|
195
|
+
: null,
|
|
161
196
|
),
|
|
162
197
|
),
|
|
163
198
|
),
|
|
164
199
|
digest ? h('p', { style: errorStyles.digestFooter }, `ERROR ${digest}`) : null,
|
|
165
200
|
),
|
|
166
|
-
)
|
|
201
|
+
)
|
|
167
202
|
}
|