From de34c1a6ffc501c1951d38df9f876aee6576a0ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Ara=C3=BAjo?= Date: Wed, 14 Oct 2026 21:03:53 -0300 Subject: [PATCH 1/2] sqlite: propagate errors from Database option getters MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The readBigInts, returnArrays, allowBareNamedParameters and allowUnknownNamedParameters options were read with `if (Get().ToLocal())`, so a throwing getter left an exception pending while the constructor carried on. Option parsing continued, the database was opened, and the exception was lost, leaving a database file on disk for a constructor call that should have failed. Return as soon as reading any of these options fails, matching how every other option is handled. Signed-off-by: Guilherme Araújo Assisted-by: Claude --- src/node_sqlite.cc | 92 ++++++++++++++------------- test/parallel/test-sqlite-database.js | 18 ++++++ 2 files changed, 66 insertions(+), 44 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index b4fbfa88746a..a65401c62e51 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -1996,63 +1996,67 @@ void Database::New(const FunctionCallbackInfo& args) { } Local read_bigints_v; - if (options->Get(env->context(), env->read_bigints_string()) - .ToLocal(&read_bigints_v)) { - if (!read_bigints_v->IsUndefined()) { - if (!read_bigints_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.readBigInts" argument must be a boolean.)"); - return; - } - open_config.set_use_big_ints(read_bigints_v.As()->Value()); + if (!options->Get(env->context(), env->read_bigints_string()) + .ToLocal(&read_bigints_v)) { + return; + } + if (!read_bigints_v->IsUndefined()) { + if (!read_bigints_v->IsBoolean()) { + THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + R"(The "options.readBigInts" argument must be a boolean.)"); + return; } + open_config.set_use_big_ints(read_bigints_v.As()->Value()); } Local return_arrays_v; - if (options->Get(env->context(), env->return_arrays_string()) - .ToLocal(&return_arrays_v)) { - if (!return_arrays_v->IsUndefined()) { - if (!return_arrays_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.returnArrays" argument must be a boolean.)"); - return; - } - open_config.set_return_arrays(return_arrays_v.As()->Value()); + if (!options->Get(env->context(), env->return_arrays_string()) + .ToLocal(&return_arrays_v)) { + return; + } + if (!return_arrays_v->IsUndefined()) { + if (!return_arrays_v->IsBoolean()) { + THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + R"(The "options.returnArrays" argument must be a boolean.)"); + return; } + open_config.set_return_arrays(return_arrays_v.As()->Value()); } Local allow_bare_named_params_v; - if (options->Get(env->context(), env->allow_bare_named_params_string()) - .ToLocal(&allow_bare_named_params_v)) { - if (!allow_bare_named_params_v->IsUndefined()) { - if (!allow_bare_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.allowBareNamedParameters" )" - "argument must be a boolean."); - return; - } - open_config.set_allow_bare_named_params( - allow_bare_named_params_v.As()->Value()); + if (!options->Get(env->context(), env->allow_bare_named_params_string()) + .ToLocal(&allow_bare_named_params_v)) { + return; + } + if (!allow_bare_named_params_v->IsUndefined()) { + if (!allow_bare_named_params_v->IsBoolean()) { + THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + R"(The "options.allowBareNamedParameters" )" + "argument must be a boolean."); + return; } + open_config.set_allow_bare_named_params( + allow_bare_named_params_v.As()->Value()); } Local allow_unknown_named_params_v; - if (options->Get(env->context(), env->allow_unknown_named_params_string()) - .ToLocal(&allow_unknown_named_params_v)) { - if (!allow_unknown_named_params_v->IsUndefined()) { - if (!allow_unknown_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.allowUnknownNamedParameters" )" - "argument must be a boolean."); - return; - } - open_config.set_allow_unknown_named_params( - allow_unknown_named_params_v.As()->Value()); + if (!options->Get(env->context(), env->allow_unknown_named_params_string()) + .ToLocal(&allow_unknown_named_params_v)) { + return; + } + if (!allow_unknown_named_params_v->IsUndefined()) { + if (!allow_unknown_named_params_v->IsBoolean()) { + THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), + R"(The "options.allowUnknownNamedParameters" )" + "argument must be a boolean."); + return; } + open_config.set_allow_unknown_named_params( + allow_unknown_named_params_v.As()->Value()); } Local defensive_v; diff --git a/test/parallel/test-sqlite-database.js b/test/parallel/test-sqlite-database.js index 79e1fe35d434..66d273b6d010 100644 --- a/test/parallel/test-sqlite-database.js +++ b/test/parallel/test-sqlite-database.js @@ -279,6 +279,24 @@ suite('Database() constructor', () => { ); }); + for (const option of [ + 'readBigInts', + 'returnArrays', + 'allowBareNamedParameters', + 'allowUnknownNamedParameters', + ]) { + test(`propagates an error thrown by the options.${option} getter`, (t) => { + const dbPath = nextDb(); + const error = new Error('boom'); + t.assert.throws(() => { + new Database(dbPath, { + get [option]() { throw error; }, + }); + }, error); + t.assert.strictEqual(existsSync(dbPath), false); + }); + } + test('has sqlite-type symbol property', (t) => { const dbPath = nextDb(); using db = new Database(dbPath); From 5f02b11471c1c86ea4dba6adf1de508b196ff32a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Guilherme=20Ara=C3=BAjo?= Date: Wed, 14 Oct 2026 23:03:09 -0300 Subject: [PATCH 2/2] sqlite: add helper for reading boolean options MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reading an optional boolean option took about 15 lines of Get/IsUndefined/IsBoolean/throw, repeated for every option across Database's constructor, prepare(), function(), aggregate() and createModule(). That repetition is also what let a missing early return slip into four of the constructor's options. Add ReadOptionalBool(), which reads one property, validates it and reports whether an exception is pending, and use it for every boolean option. Options are still read in the same order, and the error messages are unchanged. Signed-off-by: Guilherme Araújo Assisted-by: Claude --- src/node_sqlite.cc | 467 ++++++++------------------------------------- 1 file changed, 78 insertions(+), 389 deletions(-) diff --git a/src/node_sqlite.cc b/src/node_sqlite.cc index a65401c62e51..705d9b4a79a5 100644 --- a/src/node_sqlite.cc +++ b/src/node_sqlite.cc @@ -1818,6 +1818,32 @@ void Database::CreateTagStore(const FunctionCallbackInfo& args) { args.GetReturnValue().Set(session->object()); } +// Reads an optional boolean property, leaving |out| unchanged when it is +// undefined. Returns false if a JavaScript exception is pending, either from +// the property getter or because the value is not a boolean. +template +static bool ReadOptionalBool(Environment* env, + Local options, + const char* key, + T* out) { + Local key_string = + OneByteString(env->isolate(), key, -1, NewStringType::kInternalized); + Local value; + if (!options->Get(env->context(), key_string).ToLocal(&value)) { + return false; + } + if (value->IsUndefined()) { + return true; + } + if (!value->IsBoolean()) { + THROW_ERR_INVALID_ARG_TYPE( + env->isolate(), "The \"options.%s\" argument must be a boolean.", key); + return false; + } + *out = value->IsTrue(); + return true; +} + std::optional ValidateDatabasePath(Environment* env, Local path, const std::string& field_name) { @@ -1893,90 +1919,23 @@ void Database::New(const FunctionCallbackInfo& args) { } Local options = args[1].As(); - Local open_string = FIXED_ONE_BYTE_STRING(env->isolate(), "open"); - Local open_v; - if (!options->Get(env->context(), open_string).ToLocal(&open_v)) { - return; - } - if (!open_v->IsUndefined()) { - if (!open_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), "The \"options.open\" argument must be a boolean."); - return; - } - open = open_v.As()->Value(); - } - - Local read_only_string = - FIXED_ONE_BYTE_STRING(env->isolate(), "readOnly"); - Local read_only_v; - if (!options->Get(env->context(), read_only_string).ToLocal(&read_only_v)) { + bool read_only = open_config.get_read_only(); + bool enable_foreign_keys = open_config.get_enable_foreign_keys(); + bool enable_dqs = open_config.get_enable_dqs(); + if (!ReadOptionalBool(env, options, "open", &open)) return; + if (!ReadOptionalBool(env, options, "readOnly", &read_only)) return; + if (!ReadOptionalBool( + env, options, "enableForeignKeyConstraints", &enable_foreign_keys)) return; - } - if (!read_only_v->IsUndefined()) { - if (!read_only_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.readOnly\" argument must be a boolean."); - return; - } - open_config.set_read_only(read_only_v.As()->Value()); - } - - Local enable_foreign_keys_string = - FIXED_ONE_BYTE_STRING(env->isolate(), "enableForeignKeyConstraints"); - Local enable_foreign_keys_v; - if (!options->Get(env->context(), enable_foreign_keys_string) - .ToLocal(&enable_foreign_keys_v)) { - return; - } - if (!enable_foreign_keys_v->IsUndefined()) { - if (!enable_foreign_keys_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.enableForeignKeyConstraints\" argument must be a " - "boolean."); - return; - } - open_config.set_enable_foreign_keys( - enable_foreign_keys_v.As()->Value()); - } - - Local enable_dqs_string = FIXED_ONE_BYTE_STRING( - env->isolate(), "enableDoubleQuotedStringLiterals"); - Local enable_dqs_v; - if (!options->Get(env->context(), enable_dqs_string) - .ToLocal(&enable_dqs_v)) { + if (!ReadOptionalBool( + env, options, "enableDoubleQuotedStringLiterals", &enable_dqs)) return; - } - if (!enable_dqs_v->IsUndefined()) { - if (!enable_dqs_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.enableDoubleQuotedStringLiterals\" argument must be " - "a boolean."); - return; - } - open_config.set_enable_dqs(enable_dqs_v.As()->Value()); - } - - Local allow_extension_string = - FIXED_ONE_BYTE_STRING(env->isolate(), "allowExtension"); - Local allow_extension_v; - if (!options->Get(env->context(), allow_extension_string) - .ToLocal(&allow_extension_v)) { + if (!ReadOptionalBool( + env, options, "allowExtension", &allow_load_extension)) return; - } - - if (!allow_extension_v->IsUndefined()) { - if (!allow_extension_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.allowExtension\" argument must be a boolean."); - return; - } - allow_load_extension = allow_extension_v.As()->Value(); - } + open_config.set_read_only(read_only); + open_config.set_enable_foreign_keys(enable_foreign_keys); + open_config.set_enable_dqs(enable_dqs); Local timeout_v; if (!options->Get(env->context(), env->timeout_string()) @@ -1995,84 +1954,28 @@ void Database::New(const FunctionCallbackInfo& args) { open_config.set_timeout(timeout_v.As()->Value()); } - Local read_bigints_v; - if (!options->Get(env->context(), env->read_bigints_string()) - .ToLocal(&read_bigints_v)) { + bool use_big_ints = open_config.get_use_big_ints(); + bool return_arrays = open_config.get_return_arrays(); + bool allow_bare_named_params = open_config.get_allow_bare_named_params(); + bool allow_unknown_named_params = + open_config.get_allow_unknown_named_params(); + bool defensive = open_config.get_enable_defensive(); + if (!ReadOptionalBool(env, options, "readBigInts", &use_big_ints)) return; + if (!ReadOptionalBool(env, options, "returnArrays", &return_arrays)) return; + if (!ReadOptionalBool( + env, options, "allowBareNamedParameters", &allow_bare_named_params)) return; - } - if (!read_bigints_v->IsUndefined()) { - if (!read_bigints_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.readBigInts" argument must be a boolean.)"); - return; - } - open_config.set_use_big_ints(read_bigints_v.As()->Value()); - } - - Local return_arrays_v; - if (!options->Get(env->context(), env->return_arrays_string()) - .ToLocal(&return_arrays_v)) { - return; - } - if (!return_arrays_v->IsUndefined()) { - if (!return_arrays_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.returnArrays" argument must be a boolean.)"); - return; - } - open_config.set_return_arrays(return_arrays_v.As()->Value()); - } - - Local allow_bare_named_params_v; - if (!options->Get(env->context(), env->allow_bare_named_params_string()) - .ToLocal(&allow_bare_named_params_v)) { - return; - } - if (!allow_bare_named_params_v->IsUndefined()) { - if (!allow_bare_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.allowBareNamedParameters" )" - "argument must be a boolean."); - return; - } - open_config.set_allow_bare_named_params( - allow_bare_named_params_v.As()->Value()); - } - - Local allow_unknown_named_params_v; - if (!options->Get(env->context(), env->allow_unknown_named_params_string()) - .ToLocal(&allow_unknown_named_params_v)) { + if (!ReadOptionalBool(env, + options, + "allowUnknownNamedParameters", + &allow_unknown_named_params)) return; - } - if (!allow_unknown_named_params_v->IsUndefined()) { - if (!allow_unknown_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - R"(The "options.allowUnknownNamedParameters" )" - "argument must be a boolean."); - return; - } - open_config.set_allow_unknown_named_params( - allow_unknown_named_params_v.As()->Value()); - } - - Local defensive_v; - if (!options->Get(env->context(), env->defensive_string()) - .ToLocal(&defensive_v)) { - return; - } - if (!defensive_v->IsUndefined()) { - if (!defensive_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.defensive\" argument must be a boolean."); - return; - } - open_config.set_enable_defensive(defensive_v.As()->Value()); - } + if (!ReadOptionalBool(env, options, "defensive", &defensive)) return; + open_config.set_use_big_ints(use_big_ints); + open_config.set_return_arrays(return_arrays); + open_config.set_allow_bare_named_params(allow_bare_named_params); + open_config.set_allow_unknown_named_params(allow_unknown_named_params); + open_config.set_enable_defensive(defensive); // Parse limits option Local limits_v; @@ -2222,85 +2125,17 @@ void Database::Prepare(const FunctionCallbackInfo& args) { return; } Local options = args[1].As(); - - Local return_arrays_v; - if (!options->Get(env->context(), env->return_arrays_string()) - .ToLocal(&return_arrays_v)) { + if (!ReadOptionalBool(env, options, "returnArrays", &return_arrays)) return; + if (!ReadOptionalBool(env, options, "readBigInts", &use_big_ints)) return; + if (!ReadOptionalBool( + env, options, "allowBareNamedParameters", &allow_bare_named_params)) return; - } - if (!return_arrays_v->IsUndefined()) { - if (!return_arrays_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.returnArrays\" argument must be a boolean."); - return; - } - return_arrays = return_arrays_v->IsTrue(); - } - - Local read_big_ints_v; - if (!options->Get(env->context(), env->read_bigints_string()) - .ToLocal(&read_big_ints_v)) { + if (!ReadOptionalBool(env, + options, + "allowUnknownNamedParameters", + &allow_unknown_named_params)) return; - } - if (!read_big_ints_v->IsUndefined()) { - if (!read_big_ints_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.readBigInts\" argument must be a boolean."); - return; - } - use_big_ints = read_big_ints_v->IsTrue(); - } - - Local allow_bare_named_params_v; - if (!options->Get(env->context(), env->allow_bare_named_params_string()) - .ToLocal(&allow_bare_named_params_v)) { - return; - } - if (!allow_bare_named_params_v->IsUndefined()) { - if (!allow_bare_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.allowBareNamedParameters\" argument must be a " - "boolean."); - return; - } - allow_bare_named_params = allow_bare_named_params_v->IsTrue(); - } - - Local allow_unknown_named_params_v; - if (!options->Get(env->context(), env->allow_unknown_named_params_string()) - .ToLocal(&allow_unknown_named_params_v)) { - return; - } - if (!allow_unknown_named_params_v->IsUndefined()) { - if (!allow_unknown_named_params_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.allowUnknownNamedParameters\" argument must be a " - "boolean."); - return; - } - allow_unknown_named_params = allow_unknown_named_params_v->IsTrue(); - } - - Local persistent_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "persistent")) - .ToLocal(&persistent_v)) { - return; - } - if (!persistent_v->IsUndefined()) { - if (!persistent_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.persistent\" argument must be a boolean."); - return; - } - persistent = persistent_v->IsTrue(); - } + if (!ReadOptionalBool(env, options, "persistent", &persistent)) return; } // Reading the options bag above can run user JavaScript through a property @@ -2404,77 +2239,12 @@ void Database::CustomFunction(const FunctionCallbackInfo& args) { } Local options = args[1].As(); - Local use_bigint_args_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "useBigIntArguments")) - .ToLocal(&use_bigint_args_v)) { + if (!ReadOptionalBool(env, options, "useBigIntArguments", &use_bigint_args)) return; - } - - if (!use_bigint_args_v->IsUndefined()) { - if (!use_bigint_args_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.useBigIntArguments\" argument must be a boolean."); - return; - } - use_bigint_args = use_bigint_args_v.As()->Value(); - } - - Local varargs_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "varargs")) - .ToLocal(&varargs_v)) { + if (!ReadOptionalBool(env, options, "varargs", &varargs)) return; + if (!ReadOptionalBool(env, options, "deterministic", &deterministic)) return; - } - - if (!varargs_v->IsUndefined()) { - if (!varargs_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.varargs\" argument must be a boolean."); - return; - } - varargs = varargs_v.As()->Value(); - } - - Local deterministic_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "deterministic")) - .ToLocal(&deterministic_v)) { - return; - } - - if (!deterministic_v->IsUndefined()) { - if (!deterministic_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.deterministic\" argument must be a boolean."); - return; - } - deterministic = deterministic_v.As()->Value(); - } - - Local direct_only_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "directOnly")) - .ToLocal(&direct_only_v)) { - return; - } - - if (!direct_only_v->IsUndefined()) { - if (!direct_only_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.directOnly\" argument must be a boolean."); - return; - } - direct_only = direct_only_v.As()->Value(); - } + if (!ReadOptionalBool(env, options, "directOnly", &direct_only)) return; } if (!args[fn_index]->IsFunction()) { @@ -2754,60 +2524,11 @@ void Database::AggregateFunction(const FunctionCallbackInfo& args) { bool use_bigint_args = false; bool varargs = false; bool direct_only = false; - Local use_bigint_args_v; Local inverseFunc = Local(); - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "useBigIntArguments")) - .ToLocal(&use_bigint_args_v)) { - return; - } - - if (!use_bigint_args_v->IsUndefined()) { - if (!use_bigint_args_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.useBigIntArguments\" argument must be a boolean."); - return; - } - use_bigint_args = use_bigint_args_v.As()->Value(); - } - - Local varargs_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "varargs")) - .ToLocal(&varargs_v)) { + if (!ReadOptionalBool(env, options, "useBigIntArguments", &use_bigint_args)) return; - } - - if (!varargs_v->IsUndefined()) { - if (!varargs_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.varargs\" argument must be a boolean."); - return; - } - varargs = varargs_v.As()->Value(); - } - - Local direct_only_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "directOnly")) - .ToLocal(&direct_only_v)) { - return; - } - - if (!direct_only_v->IsUndefined()) { - if (!direct_only_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.directOnly\" argument must be a boolean."); - return; - } - direct_only = direct_only_v.As()->Value(); - } + if (!ReadOptionalBool(env, options, "varargs", &varargs)) return; + if (!ReadOptionalBool(env, options, "directOnly", &direct_only)) return; Local inverse_v; if (!options->Get(env->context(), env->inverse_string()) @@ -2958,42 +2679,10 @@ void Database::CreateModule(const FunctionCallbackInfo& args) { // Extract optional boolean options. bool direct_only = false; - Local direct_only_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "directOnly")) - .ToLocal(&direct_only_v)) { - return; - } - - if (!direct_only_v->IsUndefined()) { - if (!direct_only_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.directOnly\" argument must be a boolean."); - return; - } - direct_only = direct_only_v.As()->Value(); - } - bool use_bigint_args = false; - Local use_bigint_args_v; - if (!options - ->Get(env->context(), - FIXED_ONE_BYTE_STRING(env->isolate(), "useBigIntArguments")) - .ToLocal(&use_bigint_args_v)) { + if (!ReadOptionalBool(env, options, "directOnly", &direct_only)) return; + if (!ReadOptionalBool(env, options, "useBigIntArguments", &use_bigint_args)) return; - } - - if (!use_bigint_args_v->IsUndefined()) { - if (!use_bigint_args_v->IsBoolean()) { - THROW_ERR_INVALID_ARG_TYPE( - env->isolate(), - "The \"options.useBigIntArguments\" argument must be a boolean."); - return; - } - use_bigint_args = use_bigint_args_v.As()->Value(); - } // Build CREATE TABLE schema SQL from columns. std::string schema_sql = "CREATE TABLE x(";