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 <noreply@anthropic.com>
This commit is contained in:
Malte Ubl
2026-10-19 17:31:36 -07:00
co-authored by Claude Opus 5.5
parent 26946d6b22
commit b8dd7d2182
2 changed files with 6 additions and 10 deletions
@@ -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,
};
}
@@ -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; };