fix(build): don't crash on benign floating asset-import errors (#1510)#1846
Conversation
|
/bigbonk review for issues |
commit: |
|
|
/bigbonk review for issues |
|
@james-elicx Bonk workflow was cancelled. View workflow run · To retry, trigger Bonk again. |
There was a problem hiding this comment.
Review: fix(build): don't crash on benign floating asset-import errors (#1510)
Reviewed the backstop changes and tests against real Node error shapes and Next.js's documented behavior. The fix is correct and well-targeted. I verified the core claims empirically and against the Next.js source.
Verified correct
- Next.js parity is real. The exact fixture this targets is
test/e2e/react-version/pages/api/pages-api-edge-url-dep.js, whose comment literally reads// Adding URL dependency to edge api, it shouldn't break the buildand does a floatingimport(new URL('./style.css', import.meta.url).href). So treating these as benign matches Next.js intent. - Error shapes match. I reproduced both branches on Node:
- On-disk asset →
ERR_UNKNOWN_FILE_EXTENSIONwithurl: undefinedand the ext in the message (Unknown file extension ".css" for /...). The regex/extension\s+"([^"]+)"/+toLowerCase()allow-list handles this, including uppercase exts and paths containing stray quotes. - Missing asset →
ERR_MODULE_NOT_FOUNDwithurlpopulated. Theurl-extension check handles this, including?v=query suffixes (covered by a test).
- On-disk asset →
- Allow-list scoping is sound. Excluding
.js/.mjs/.ts/extensionless means genuine missing-module bugs still crash. In a Vite server bundle, CSS/asset imports are build-time transforms; a runtimeimport()of a.cssreaching Node can only ever fail benignly, so the absorption is safe. - Handler precedence is deliberate and documented.
absorbBenignAssetImportruns before theVINEXT_PRERENDERre-throw, so benign asset imports are swallowed even during prerender (intended — "so the build doesn't fail"). This is a documented, narrow exception to the otherwise re-throw-everything prerender stance. vp checkpasses (format + lint + types) on both files; the test file passes (8 tests).
Non-blocking observations
-
.wasmin the allow-list is effectively dead for the on-disk case. Node loads.wasmnatively, so a present-on-disk wasm asset throws a WebAssemblyCompileError(nocode), notERR_UNKNOWN_FILE_EXTENSION— it won't be matched by the extension branch. A missing.wasmstill matches via theERR_MODULE_NOT_FOUNDurlbranch, so the entry isn't entirely useless, but the on-disk path won't trigger. Minor; worth a one-line comment to avoid future confusion. Not a correctness issue. -
Installed-handler behavior is untested. The new tests cover the pure predicates (
isBenignAssetImportError,peerDisconnectCode) and the test-runner install skip, which is the right unit boundary. But the interaction — specifically that a benign asset import is absorbed even whenVINEXT_PRERENDER=1(the precedence that makes this fix work during build) — has no direct test. Since the listener is gated off under Vitest, you'd need to invoke the handler body directly (e.g. extract anabsorbBenignAssetImport-style pure function that takes the env state, or test the registered callback). Consider adding one test asserting "benign asset import is absorbed;VINEXT_PRERENDERre-throw does not pre-empt it" to lock in the ordering against future refactors. -
Comment accuracy nit (line 99-100): the doc says
ERR_UNKNOWN_FILE_EXTENSION (asset present)/ERR_MODULE_NOT_FOUND (asset not co-located)— accurate, but note.jsonand.wasmare special-cased by Node (ERR_IMPORT_ATTRIBUTE_MISSING/ WebAssembly errors respectively) and won't hit either branch when present. The allow-list correctly omits.json; only the.wasmmention is slightly aspirational.
Conclusion
The change is correct, conservative, and faithful to Next.js behavior. The only thing I'd genuinely push for before merge is observation #2 — a test that pins the benign-absorb-before-prerender-rethrow ordering, since that precedence is the load-bearing part of the fix and is currently only asserted by the predicate tests, not the handler. The .wasm/comment items are cosmetic.
|
Review posted to PR #1846. SummaryI reviewed the PR's changes to Verdict: the fix is correct and well-targeted. Key verifications:
Non-blocking items flagged:
|
Fixes #1510 — the
react-versionandtwoslashtest apps crashed the server (exit 7/1) when a floating (un-awaited)import()of an asset failed to resolve: theuncaughtException/unhandledRejectionbackstop re-threw it and took down the process. The backstop now swallows benign asset-import resolution errors (matching Next.js's non-crashing stance) so the build/serve completes; genuine JS/TS module errors still surface. Tests added insocket-error-backstop.test.ts. Closes #1510