From b8dd7d2182010c8efd9aeccadeb95f483531cf0e Mon Sep 17 00:00:00 2001 From: Malte Ubl Date: Mon, 19 Oct 2026 17:31:36 -0700 Subject: [PATCH] Throw MODULE_NOT_FOUND with its code from statement-level requires A statement-level require() of a package nothing installed threw a plain Error; the expression form already carried Node's MODULE_NOT_FOUND code. Co-Authored-By: Claude Opus 5.5 --- .../compiler/src/frontend/lowering/lower-stmts.ts | 14 +++++--------- tests/corpus/2195-require-missing-package/lib.cjs | 2 +- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/compiler/src/frontend/lowering/lower-stmts.ts b/packages/compiler/src/frontend/lowering/lower-stmts.ts index 36abb9130..74690c918 100644 --- a/packages/compiler/src/frontend/lowering/lower-stmts.ts +++ b/packages/compiler/src/frontend/lowering/lower-stmts.ts @@ -2,7 +2,7 @@ import { matchAllRowsReadByElements, storedMatchAllRowsReadByElements, } from "./containers/match-row-uses.js"; -import { dynUndefinedExpr, numLit, varRef } from "../../ir/build.js"; +import { dynUndefinedExpr, nodeThrowExpr, numLit, varRef } from "../../ir/build.js"; import { lowerCollectionSpread } from "./containers/collection-methods.js"; import { lowerEventObjectPropertyWrite } from "./lower-event-target.js"; import { lowerDynObjectLiteral } from "./expressions/object-literals.js"; @@ -6600,16 +6600,12 @@ export function lowerExprStatement(lowerer: Lowerer, expr: ts.Expression): IrStm if (!isRelativeSpecifier(spec) && canonicalBuiltinModule(spec) === null) { const refusal = probeNodeRequireRefusal(sf.fileName, spec); if (refusal !== null) { + // The same throw as the expression form (cjs-inline-require): + // an Error carrying Node's MODULE_NOT_FOUND code. const loc = locOf(expr); return { - kind: "throw", - value: { - kind: "libCall", - fn: "error.new", - args: [{ kind: "strLit", value: refusal.message, type: STRING, loc }], - type: { kind: "object", className: "%Error" }, - loc, - }, + kind: "exprStmt", + expr: nodeThrowExpr(0, "MODULE_NOT_FOUND", refusal.message, VOID, loc), loc, }; } diff --git a/tests/corpus/2195-require-missing-package/lib.cjs b/tests/corpus/2195-require-missing-package/lib.cjs index 541bae658..f8d0bd73a 100644 --- a/tests/corpus/2195-require-missing-package/lib.cjs +++ b/tests/corpus/2195-require-missing-package/lib.cjs @@ -4,6 +4,6 @@ try { require("scriptc-test-definitely-not-installed"); status = "installed"; } catch (e) { - status = "missing: " + String(e.message).split("\n")[0]; + status = "missing: " + e.code + " " + String(e.message).split("\n")[0]; } exports.probe = function probe() { return status; };