Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
94c610d
node errors: only give ERR_* codes the bracketed toString()
robobun Aug 16, 2026
a58615f
Make the code property of NodeError instances enumerable
robobun Sep 6, 2026
3e90537
Mint the own code from the table literal and leave Error warnings unt…
robobun Sep 6, 2026
ba647b4
test: use a concrete deprecation code in the emitWarning passthrough …
robobun Sep 6, 2026
83a4fe6
Shorten comments
robobun Sep 6, 2026
dd20209
Keep the code in NodeError toString independent of this.code
robobun Sep 6, 2026
06af0af
Shorten the errorCodeIs comment
robobun Sep 6, 2026
bfd2ee6
Merge branch 'main' into robobun/f4e8da95/enumerable-error-code
robobun Nov 5, 2026
d2b6125
node errors: put an own enumerable code on ERR_* errors in one ErrorC…
robobun Nov 5, 2026
c72185d
Merge branch 'main' into robobun/f4e8da95/enumerable-error-code
robobun Nov 6, 2026
6c08701
child_process: link the line of Node that stamps the syscall
robobun Nov 6, 2026
947886b
node errors: keep the name of the kind on the per-code prototype
robobun Nov 6, 2026
8438a18
Move the tests of what spawn() throws to child_process-node.test.js
robobun Nov 6, 2026
caf19d4
child_process: use the captured Object.hasOwn in the catch of spawn()
robobun Nov 6, 2026
467d736
node errors: give the bracketed toString() only to the rows that are …
robobun Nov 7, 2026
8925793
node errors: mark the rows whose error Node makes in native code only
robobun Nov 7, 2026
0239b50
Merge the earlier head of this branch
robobun Nov 7, 2026
42ce11a
node errors: assert that toString is not an own property and that uti…
robobun Nov 7, 2026
702b049
node errors: mark ERR_CRYPTO_TIMING_SAFE_EQUAL_LENGTH, ERR_DLOPEN_FAI…
robobun Nov 7, 2026
2a27847
node errors: shorter comments at plain() and in the table of built-ins
robobun Nov 7, 2026
8106bf2
node errors: one-line comments at plain() and in the table of built-ins
robobun Nov 7, 2026
ce9cf9e
node errors: add a producer of ERR_STRING_TOO_LONG to the fixture, an…
robobun Nov 7, 2026
4d52024
node errors: skip the 2 GiB producer of ERR_STRING_TOO_LONG on a smal…
robobun Nov 7, 2026
d6c6f6f
node errors: the test decides once which row the fixture leaves out o…
robobun Nov 7, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions bench/snippets/node-error-code.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// What it costs to make, throw and catch an error that has a Node `code`, for each way into the table of codes.
import { EventEmitter } from "node:events";
import { join } from "node:path";
import { setTimeout as sleep } from "node:timers/promises";
import { bench, run } from "../runner.mjs";

const emitter = new EventEmitter();
const aborted = AbortSignal.abort();
const errors = Array.from({ length: 1024 }, () => {
try {
Buffer.alloc(-1);
} catch (e) {
return e;
}
});

bench("throw new RangeError() (no code)", () => {
try {
throw new RangeError("x");
} catch {}
});

bench("Buffer.alloc(-1): ERR_OUT_OF_RANGE from C++", () => {
try {
Buffer.alloc(-1);
} catch {}
});

bench("path.join(1): ERR_INVALID_ARG_TYPE from Rust", () => {
try {
join(1);
} catch {}
});

bench("emitter.on('a', 1): ERR_INVALID_ARG_TYPE from a built-in module", () => {
try {
emitter.on("a", 1);
} catch {}
});

bench("process.cpuUsage({ user: -1 }): the RangeError of ERR_INVALID_ARG_VALUE", () => {
try {
process.cpuUsage({ user: -1, system: 0 });
} catch {}
});

bench("timers/promises setTimeout with an aborted signal: ABORT_ERR", async () => {
try {
await sleep(1, undefined, { signal: aborted });
} catch {}
});

let index = 0;
bench("read error.code", () => {
return errors[index++ & 1023].code;
});

await run();
14 changes: 9 additions & 5 deletions src/codegen/builtins/host/private-globals.builtins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,16 @@ const asksCellForItsClass = {
implementation: b.hostCall,
} satisfies b.FunctionField;

// ErrorCode.cpp: an error with a code is an instance of the kind of error the code stands for, with an object of its own for each code in front of the prototype of that kind.
// ErrorCode.cpp: the error has `code`, and the prototype of its code has `name` and, unless the row is plain(), the bracketed toString.
const kindsOfErrorsWithCode = ["Error", "TypeError", "RangeError", "SyntaxError", "URIError"];
const [firstKind, ...otherKinds] = kindsOfErrorsWithCode.map(kind => b.instance(kind));
const newErrorWithCode = b.union(firstKind, ...otherKinds).unaliased;
const printsErrorWithCode = b.builtin("%NativeFunctions%.ErrorCodeCppNodeError_proto_toString");
const membersInheritedByErrorWithCode = { name: b.string, code: b.string, toString: printsErrorWithCode };
const membersOfErrorWithCode = {
name: b.string,
code: b.string,
toString: b.union(printsErrorWithCode, b.builtin("Error.prototype.toString")),
};

// The message reads constructor.name of a value, converts it to a string, or prints it the way console.log does.
const formattedInMessage = [b.printedByFormatter("constructor")];
Expand Down Expand Up @@ -67,7 +71,7 @@ const makesErrorWithCode = [
args: { code: b.int(first, last), operands: b.any.rest },
returns: newErrorWithCode,
// ERR_SSL_NO_CIPHER_MATCH.
resultProperties: { ...membersInheritedByErrorWithCode, reason: b.string, library: b.string },
resultProperties: { ...membersOfErrorWithCode, reason: b.string, library: b.string },
Comment thread
robobun marked this conversation as resolved.
Resolved
capability: "js",
throws: true,
runsOnlyOperandCode: true,
Expand All @@ -82,7 +86,7 @@ const makesAbortError = [
{
args: { message: b.string.optional, options: b.undefined.optional },
returns: b.instance("Error").unaliased,
resultProperties: membersInheritedByErrorWithCode,
resultProperties: { name: b.string, code: b.string },
capability: "heap",
implementation: b.hostCall,
},
Expand Down Expand Up @@ -112,7 +116,7 @@ const looksAtPromise = (returns: b.TableType, otherwise: b.TableType, uses: read
const closedPromise = b.instance("Promise").holding({ value: b.undefined, reason: b.any });

export default b.declarations(
// Each of those objects has a function of its own, and one entry stands for them all. It reads the three members of its receiver and converts each to a string.
// Each of those objects has a function of its own, and one entry stands for them all. It reads the name and the message of its receiver and converts each to a string. The code it prints is the one its function was made with, and the function of a SystemError code reads the code of its receiver.
b.hostFunction(printsErrorWithCodeCell, "ErrorCode.cpp", "NodeError_proto_toString", {
this: b.any,
returns: b.string,
Expand Down
31 changes: 25 additions & 6 deletions src/codegen/generate-node-errors.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { readFileSync } from "node:fs";
import path from "node:path";
import NodeErrors from "../jsc/bindings/ErrorCode.ts";
import NodeErrors, { plainErrorCodes } from "../jsc/bindings/ErrorCode.ts";
import { writeIfNotChanged } from "./helpers.ts";
const outputDir = process.argv[2];
const typesDir = process.argv[3];
Expand All @@ -19,6 +19,11 @@ if (count > 1 << 16) {
throw new Error(`NodeError can't fit ${count} codes in a u16`);
}

// A name that is not the name of the row's constructor is a property of the error itself, as in Node's AbortError and UnhandledPromiseRejection: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/errors.js#L985-L986 and https://github.com/nodejs/node/blob/v26.3.0/lib/internal/process/promises.js#L47-L48
const ownNames = [
...new Set(NodeErrors.flatMap(([, constructor, name]) => (name != null && name !== constructor.name ? [name] : []))),
].sort();

let enumHeader = ``;
let listHeader = ``;
let rustConsts = ``;
Expand All @@ -35,6 +40,7 @@ enumHeader = `

namespace Bun {
static constexpr size_t NODE_ERROR_COUNT = ${count};
static constexpr size_t NODE_ERROR_OWN_NAME_COUNT = ${ownNames.length};
enum class ErrorCode : uint16_t {
`;

Expand All @@ -45,14 +51,26 @@ listHeader = `

#include <JavaScriptCore/ErrorType.h>

enum class ErrorOwnName : uint8_t { None, ${ownNames.join(", ")} };

struct ErrorCodeData {
JSC::ErrorType type;
// Not None: an error of this row gets \`name\` as a property of its own.
ErrorOwnName ownName;
// The prototype of the code has the \`name [code]: message\` toString() of Node's NodeError. Without it the error inherits Error.prototype.toString.
bool hasNodeErrorToString;
WTF::ASCIILiteral name;
WTF::ASCIILiteral code;
};
static constexpr ErrorCodeData errors[${count}] = {

const ErrorCodeData& ErrorCodeCache::dataFor(ErrorCode code)
{
static constexpr ErrorCodeData errors[${count}] = {
`;

// Every code that Node registers for makeNodeErrorWithCode starts with ERR_.
const hasNodeErrorToString = (code: string) => code.startsWith("ERR_") && !plainErrorCodes.has(code);

let i = 0;
for (let [code, constructor, name, ...other_constructors] of NodeErrors) {
if (name == null) name = constructor.name;
Expand All @@ -61,7 +79,7 @@ for (let [code, constructor, name, ...other_constructors] of NodeErrors) {
const codeWithoutPrefix = code === "ERR_MODULE_NOT_FOUND" ? code : code.replace(/^ERR_/, "");

enumHeader += ` ${code} = ${i},\n`;
listHeader += ` { JSC::ErrorType::${constructor.name}, "${name}"_s, "${code}"_s },\n`;
listHeader += ` { JSC::ErrorType::${constructor.name}, ErrorOwnName::${name === constructor.name ? "None" : name}, ${hasNodeErrorToString(code)}, "${name}"_s, "${code}"_s },\n`;
rustConsts += ` /// \`${code}\` (instanceof ${constructor.name})\n`;
rustConsts += ` pub const ${codeWithoutPrefix}: ErrorCode = ErrorCode(${i});\n`;
if (codeWithoutPrefix !== code) {
Expand All @@ -74,7 +92,7 @@ for (let [code, constructor, name, ...other_constructors] of NodeErrors) {
if (con == null) continue;
if (name == null) name = con.name;
enumHeader += ` ${code}_${con.name} = ${i},\n`;
listHeader += ` { JSC::ErrorType::${con.name}, "${con.name}"_s, "${code}"_s },\n`;
listHeader += ` { JSC::ErrorType::${con.name}, ErrorOwnName::None, ${hasNodeErrorToString(code)}, "${con.name}"_s, "${code}"_s },\n`;
rustConsts += ` /// \`${code}\` (instanceof ${con.name})\n`;
rustConsts += ` pub const ${codeWithoutPrefix}_${con.name}: ErrorCode = ErrorCode(${i});\n`;
rustCodeStr += ` "${code}",\n`;
Expand All @@ -87,8 +105,9 @@ enumHeader += `
} // namespace Bun
`;

listHeader += `
};
listHeader += ` };
return errors[static_cast<size_t>(code)];
}
`;

const rustSource = `\
Expand Down
1 change: 0 additions & 1 deletion src/js/internal/fs/cp-sync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ function decorateSystemError(err: SystemError, prefix: string, context: SystemEr
if (path !== undefined) message += ` ${path}`;
if (dest !== undefined) message += ` => ${dest}`;
err.message = message;
err.name = "SystemError";
err.info = context;
err.errno = errno;
err.syscall = syscall;
Expand Down
5 changes: 3 additions & 2 deletions src/js/node/child_process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1540,7 +1540,7 @@ class ChildProcess extends EventEmitter {
}
} catch (ex) {
const exCode =
ex != null && typeof ex === "object" && Object.hasOwn(ex, "code") ? (ex as SystemError).code : undefined;
ex != null && typeof ex === "object" && ObjectHasOwn(ex, "code") ? (ex as SystemError).code : undefined;
if (
// node sends these errors on the next tick rather than throwing
exCode === "EACCES" ||
Expand All @@ -1563,7 +1563,8 @@ class ChildProcess extends EventEmitter {
this.#stdioOptions[2] = "undefined";
}
} else {
if (exCode !== undefined) {
// Only an errno error is an ErrnoException(err, "spawn") in Node: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/child_process.js#L440. An ERR_* validation error has an own `code` too.
if (exCode !== undefined && ObjectHasOwn(ex as SystemError, "errno")) {
// Node throws errors that are not in the deferred list above
// synchronously, with `syscall: "spawn"` (no file appended).
(ex as SystemError).syscall = "spawn";
Expand Down
92 changes: 54 additions & 38 deletions src/jsc/bindings/ErrorCode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,16 @@ JSC_DEFINE_HOST_FUNCTION(NodeError_proto_toString, (JSC::JSGlobalObject * global
auto scope = DECLARE_THROW_SCOPE(vm);
auto thisVal = callFrame->thisValue().toThis(globalObject, JSC::ECMAMode::strict());

// The function of a code holds the code, as the toString of Node's NodeError closes over it: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/errors.js#L462-L464
JSC::JSValue code = callFrame->jsCallee()->getDirect(vm, WebCore::builtinNames(vm).codePrivateName());

auto name = thisVal.get(globalObject, vm.propertyNames->name);
RETURN_IF_EXCEPTION(scope, {});
auto code = thisVal.get(globalObject, WebCore::builtinNames(vm).codePublicName());
RETURN_IF_EXCEPTION(scope, {});
// The function of a SystemError code holds none, as that toString reads `this.code`: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/errors.js#L386-L388
if (!code) {
code = thisVal.get(globalObject, WebCore::builtinNames(vm).codePublicName());
RETURN_IF_EXCEPTION(scope, {});
}
auto message = thisVal.get(globalObject, vm.propertyNames->message);
RETURN_IF_EXCEPTION(scope, {});

Expand Down Expand Up @@ -107,11 +113,13 @@ namespace Bun {
using namespace JSC;
using namespace WTF;

static JSC::JSObject* createErrorPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code)
#include "ErrorCode+Data.h"

JSC::JSObject* ErrorCodeCache::createPrototype(JSC::VM& vm, JSC::JSGlobalObject* globalObject, const ErrorCodeData& data, JSC::JSString* code)
{
JSC::JSObject* prototype;

switch (type) {
switch (data.type) {
case JSC::ErrorType::TypeError:
prototype = JSC::constructEmptyObject(globalObject, globalObject->m_typeErrorStructure.prototype(globalObject));
break;
Expand Down Expand Up @@ -141,17 +149,29 @@ static JSC::JSObject* createErrorPrototype(JSC::VM& vm, JSC::JSGlobalObject* glo
break;
}

prototype->putDirect(vm, vm.propertyNames->name, jsString(vm, String(name)), 0);
prototype->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), jsString(vm, String(code)), 0);
prototype->putDirect(vm, vm.propertyNames->toString, JSC::JSFunction::create(vm, globalObject, 0, "toString"_s, NodeError_proto_toString, JSC::ImplementationVisibility::Private), 0);
// The name of the kind, also where that is not "Error": ErrorInstance::sanitizedNameString() looks at the error and at this object only, and then answers "Error".
prototype->putDirect(vm, vm.propertyNames->name, jsString(vm, String(JSC::errorTypeName(data.type))), JSC::PropertyAttribute::DontEnum | 0);
if (data.hasNodeErrorToString) {
auto* toString = JSC::JSFunction::create(vm, globalObject, 0, "toString"_s, NodeError_proto_toString, JSC::ImplementationVisibility::Private);
if (data.ownName != ErrorOwnName::SystemError)
toString->putDirect(vm, WebCore::builtinNames(vm).codePrivateName(), code, JSC::PropertyAttribute::DontEnum | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::DontDelete);
prototype->putDirect(vm, vm.propertyNames->toString, toString, JSC::PropertyAttribute::DontEnum | 0);
}

return prototype;
}

#include "ErrorCode+Data.h"
static unsigned ownNameField(ErrorOwnName name)
{
ASSERT(name != ErrorOwnName::None);
return 2 * NODE_ERROR_COUNT + static_cast<unsigned>(name) - 1;
}

const ClassInfo ErrorCodeCache::s_info = { "ErrorCodeCache"_s, &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(ErrorCodeCache) };

// The cache is one cell of an IsoSubspace, and such a cell has to fit in a MarkedBlock.
static_assert(sizeof(ErrorCodeCache) <= JSC::MarkedBlock::payloadSize);

ErrorCodeCache::ErrorCodeCache(VM& vm, Structure* structure)
: Base(vm, structure)
{
Expand Down Expand Up @@ -184,7 +204,7 @@ void ErrorCodeCache::finishCreation(VM& vm)
Base::finishCreation(vm);
ASSERT(inherits(info()));

for (unsigned i = 0; i < NODE_ERROR_COUNT; i++) {
for (unsigned i = 0; i < numberOfInternalFields; i++) {
this->internalField(i).clear();
}
}
Expand All @@ -195,23 +215,32 @@ static ErrorCodeCache* errorCache(Zig::GlobalObject* globalObject)
}

// clang-format on
static Structure* createErrorStructure(JSC::VM& vm, JSGlobalObject* globalObject, JSC::ErrorType type, WTF::ASCIILiteral name, WTF::ASCIILiteral code)
JSObject* ErrorCodeCache::createInstance(VM& vm, Zig::GlobalObject* globalObject, ErrorCode code, const String& message, JSValue cause)
{
auto* prototype = createErrorPrototype(vm, globalObject, type, name, code);
return ErrorInstance::createStructure(vm, globalObject, prototype);
const auto& data = dataFor(code);
auto& structureField = internalField(static_cast<unsigned>(code));
auto& codeField = internalField(NODE_ERROR_COUNT + static_cast<unsigned>(code));
if (!structureField) {
auto* codeString = jsString(vm, String(data.code));
codeField.set(vm, this, codeString);
if (data.ownName != ErrorOwnName::None && !internalField(ownNameField(data.ownName)))
internalField(ownNameField(data.ownName)).set(vm, this, jsString(vm, String(data.name)));
auto* prototype = createPrototype(vm, globalObject, data, codeString);
structureField.set(vm, this, ErrorInstance::createStructure(vm, globalObject, prototype));
}

auto* error = ErrorInstance::create(vm, uncheckedDowncast<Structure>(structureField.get()), message, cause, nullptr, RuntimeType::TypeNothing, data.type, true);
// `code` is a class field of Node's errors, so it is own, enumerable, and ahead of what a producer adds: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/errors.js#L441
error->putDirect(vm, WebCore::builtinNames(vm).codePublicName(), codeField.get(), 0);
// Node's SystemError is the one whose own `name` is not enumerable: https://github.com/nodejs/node/blob/v26.3.0/lib/internal/errors.js#L303-L309
if (data.ownName != ErrorOwnName::None)
error->putDirect(vm, vm.propertyNames->name, internalField(ownNameField(data.ownName)).get(), data.ownName == ErrorOwnName::SystemError ? static_cast<unsigned>(PropertyAttribute::DontEnum) : 0);
return error;
}

JSObject* ErrorCodeCache::createError(VM& vm, Zig::GlobalObject* globalObject, ErrorCode code, JSValue message, JSValue options)
{
auto scope = DECLARE_TOP_EXCEPTION_SCOPE(vm);
auto* cache = errorCache(globalObject);
const auto& data = errors[static_cast<size_t>(code)];
if (!cache->internalField(static_cast<unsigned>(code))) {
auto* structure = createErrorStructure(vm, globalObject, data.type, data.name, data.code);
cache->internalField(static_cast<unsigned>(code)).set(vm, cache, structure);
}

auto* structure = uncheckedDowncast<Structure>(cache->internalField(static_cast<unsigned>(code)).get());

// Convert the message and `cause` here rather than in ErrorInstance::create(JSGlobalObject*, ...),
// which hands back nullptr when that conversion is interrupted: every caller throws or rejects with
Expand All @@ -231,12 +260,13 @@ JSObject* ErrorCodeCache::createError(VM& vm, Zig::GlobalObject* globalObject, E
return object;
}
}
return JSC::ErrorInstance::create(vm, structure, messageString, cause, nullptr, JSC::RuntimeType::TypeNothing, data.type, true);
return createInstance(vm, globalObject, code, messageString, cause);
}

NEVER_INLINE JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, ErrorCode code, const String& message)
{
return errorCache(globalObject)->createError(vm, globalObject, code, jsString(vm, message), jsUndefined());
// Every caller means an own `message`: a null String stands for the empty one.
return errorCache(globalObject)->createInstance(vm, globalObject, code, message.isNull() ? emptyString() : message, JSValue());
}

JSObject* createError(Zig::GlobalObject* globalObject, ErrorCode code, const String& message)
Expand All @@ -251,15 +281,7 @@ NEVER_INLINE JSObject* createError(VM& vm, JSC::JSGlobalObject* globalObject, Er

JSObject* createError(VM& vm, JSC::JSGlobalObject* globalObject, ErrorCode code, JSValue message)
{
if (auto* zigGlobalObject = dynamicDowncast<Zig::GlobalObject>(globalObject))
return createError(vm, zigGlobalObject, code, message, jsUndefined());

auto* structure = createErrorStructure(vm, globalObject, errors[static_cast<size_t>(code)].type, errors[static_cast<size_t>(code)].name, errors[static_cast<size_t>(code)].code);
auto scope = DECLARE_TOP_EXCEPTION_SCOPE(vm);
String messageString = message.isUndefined() ? String() : message.toWTFString(globalObject);
if (scope.exception() && !vm.hasPendingTerminationException())
(void)scope.tryClearException();
return JSC::ErrorInstance::create(vm, structure, messageString, JSValue(), nullptr, JSC::RuntimeType::TypeNothing, errors[static_cast<size_t>(code)].type, true);
return createError(vm, defaultGlobalObject(globalObject), code, message, jsUndefined());
}

JSC::JSObject* createError(VM& vm, Zig::GlobalObject* globalObject, ErrorCode code, JSValue message, JSValue options)
Expand Down Expand Up @@ -1315,7 +1337,6 @@ JSC::EncodedJSValue INVALID_ARG_VALUE(JSC::ThrowScope& throwScope, JSC::JSGlobal
}
JSC::EncodedJSValue INVALID_ARG_VALUE_RangeError(JSC::ThrowScope& throwScope, JSC::JSGlobalObject* globalObject, WTF::ASCIILiteral name, JSC::JSValue value, const WTF::String& reason)
{
auto& vm = JSC::getVM(globalObject);
ASCIILiteral type = StringView(name).contains('.') ? "property"_s : "argument"_s;
MessageBuilder builder;

Expand All @@ -1329,12 +1350,7 @@ JSC::EncodedJSValue INVALID_ARG_VALUE_RangeError(JSC::ThrowScope& throwScope, JS
JSValueToStringSafe(globalObject, builder, value, true);
RELEASE_RETURN_IF_EXCEPTION(throwScope, {});

auto message = builder.finish(globalObject, throwScope);
RELEASE_RETURN_IF_EXCEPTION(throwScope, {});

auto* structure = createErrorStructure(vm, globalObject, ErrorType::RangeError, "RangeError"_s, "ERR_INVALID_ARG_VALUE"_s);
auto error = JSC::ErrorInstance::create(vm, structure, message, jsUndefined(), nullptr, JSC::RuntimeType::TypeNothing, ErrorType::RangeError, true);
throwScope.throwException(globalObject, error);
throwScope.throwException(globalObject, createError(globalObject, ErrorCode::ERR_INVALID_ARG_VALUE_RangeError, builder));
throwScope.release();
return {};
}
Expand Down
Loading
Loading