From 6c1c2f5e42f6a053831f5c0bac4f0db3960215dc Mon Sep 17 00:00:00 2001 From: Geoffrey Booth Date: Mon, 9 Oct 2023 21:01:42 -0700 Subject: [PATCH] vm.internalCompileFunction can now optionally return errors instead of throwing them --- doc/api/vm.md | 4 +++- lib/internal/vm.js | 32 ++++++++++++++++++++++++++++++++ src/node_contextify.cc | 12 +++++++++++- 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/doc/api/vm.md b/doc/api/vm.md index e5c116d54af0bf..59ad4a38aa0c1a 100644 --- a/doc/api/vm.md +++ b/doc/api/vm.md @@ -1027,7 +1027,9 @@ changes: * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is recommended in order to take advantage of error tracking, and to avoid issues with namespaces that contain `then` function exports. -* Returns: {Function} + * `shouldThrowOnError` {boolean} Whether compilation errors will be thrown or + returned. **Default:** `true`. +* Returns: {Function | Error} Compiles the given code into the provided context (if no context is supplied, the current context is used), and returns it wrapped inside a diff --git a/lib/internal/vm.js b/lib/internal/vm.js index f348ef6d2d612f..9ce3dc8c31f4ef 100644 --- a/lib/internal/vm.js +++ b/lib/internal/vm.js @@ -24,12 +24,36 @@ const { ERR_INVALID_ARG_TYPE, } = require('internal/errors').codes; +/** + * Checks if the given object is a context object. + * @param {object} object - The object to check. + * @returns {boolean} - Returns true if the object is a context object, else false. + */ function isContext(object) { validateObject(object, 'object', kValidateObjectAllowArray); return _isContext(object); } +/** + * Compiles a function from the given code string. + * @param {string} code - The code string to compile. + * @param {string[]} [params] - An optional array of parameter names for the compiled function. + * @param {object} [options] - An optional object containing compilation options. + * @param {string} [options.filename=''] - The filename to use for the compiled function. + * @param {number} [options.columnOffset=0] - The column offset to use for the compiled function. + * @param {number} [options.lineOffset=0] - The line offset to use for the compiled function. + * @param {Buffer} [options.cachedData=undefined] - The cached data to use for the compiled function. + * @param {boolean} [options.produceCachedData=false] - Whether to produce cached data for the compiled function. + * @param {ReturnType(); } + // Argument 10: Whether to throw errors or return them (optional) + bool should_throw_on_error = true; + if (!args[9]->IsUndefined()) { + CHECK(args[9]->IsBoolean()); + should_throw_on_error = args[9]->BooleanValue(args.GetIsolate()); + } + // Read cache from cached data buffer ScriptCompiler::CachedData* cached_data = nullptr; if (!cached_data_buf.IsEmpty()) { @@ -1273,7 +1280,10 @@ void ContextifyContext::CompileFunction( if (!maybe_fn.ToLocal(&fn)) { if (try_catch.HasCaught() && !try_catch.HasTerminated()) { errors::DecorateErrorStack(env, try_catch); - try_catch.ReThrow(); + if (should_throw_on_error) + try_catch.ReThrow(); + else + args.GetReturnValue().Set(try_catch.Exception()); } return; }