Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

src: assign ERR_SCRIPT_EXECUTION_* codes in C++ #20147

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
4 changes: 4 additions & 0 deletions doc/api/errors.md
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,10 @@ An attempt was made to `require()` an [ES6 module][].
Script execution was interrupted by `SIGINT` (For example, when Ctrl+C was
pressed).

### ERR_SCRIPT_EXECUTION_TIMEOUT

Script execution timed out, possibly due to bugs in the script being executed.

<a id="ERR_SERVER_ALREADY_LISTEN"></a>
### ERR_SERVER_ALREADY_LISTEN

Expand Down
2 changes: 1 addition & 1 deletion lib/internal/errors.js
Original file line number Diff line number Diff line change
Expand Up @@ -952,7 +952,7 @@ E('ERR_NO_LONGER_SUPPORTED', '%s is no longer supported', Error);
E('ERR_OUT_OF_RANGE', outOfRange, RangeError);
E('ERR_REQUIRE_ESM', 'Must use import to load ES Module: %s', Error);
E('ERR_SCRIPT_EXECUTION_INTERRUPTED',
'Script execution was interrupted by `SIGINT`.', Error);
'Script execution was interrupted by `SIGINT`', Error);
E('ERR_SERVER_ALREADY_LISTEN',
'Listen method has been called more than once without closing.', Error);
E('ERR_SERVER_NOT_RUNNING', 'Server is not running.', Error);
Expand Down
4 changes: 2 additions & 2 deletions src/module_wrap.cc
Original file line number Diff line number Diff line change
Expand Up @@ -286,9 +286,9 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo<Value>& args) {
// which this timeout is nested, so check whether one of the watchdogs
// from this invocation is responsible for termination.
if (timed_out) {
env->ThrowError("Script execution timed out.");
THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
} else if (received_signal) {
env->ThrowError("Script execution interrupted.");
THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/node_contextify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.

#include "node_errors.h"
#include "node_internals.h"
#include "node_watchdog.h"
#include "base_object-inl.h"
Expand Down Expand Up @@ -858,9 +859,9 @@ class ContextifyScript : public BaseObject {
// which this timeout is nested, so check whether one of the watchdogs
// from this invocation is responsible for termination.
if (timed_out) {
env->ThrowError("Script execution timed out.");
node::THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, timeout);
} else if (received_signal) {
env->ThrowError("Script execution interrupted.");
node::THROW_ERR_SCRIPT_EXECUTION_INTERRUPTED(env);
}
}

Expand Down
17 changes: 16 additions & 1 deletion src/node_errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
#include "env-inl.h"
#include "v8.h"

// Use ostringstream to print exact-width integer types
// because the format specifiers are not available on AIX.
#include <sstream>

namespace node {

// Helpers to construct errors similar to the ones provided by
Expand All @@ -24,6 +28,8 @@ namespace node {
V(ERR_MEMORY_ALLOCATION_FAILED, Error) \
V(ERR_MISSING_ARGS, TypeError) \
V(ERR_MISSING_MODULE, Error) \
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, Error) \
V(ERR_SCRIPT_EXECUTION_TIMEOUT, Error) \
V(ERR_STRING_TOO_LONG, Error) \
V(ERR_BUFFER_TOO_LARGE, Error)

Expand All @@ -49,7 +55,9 @@ namespace node {

#define PREDEFINED_ERROR_MESSAGES(V) \
V(ERR_INDEX_OUT_OF_RANGE, "Index out of range") \
V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory")
V(ERR_MEMORY_ALLOCATION_FAILED, "Failed to allocate memory") \
V(ERR_SCRIPT_EXECUTION_INTERRUPTED, \
"Script execution was interrupted by `SIGINT`")

#define V(code, message) \
inline v8::Local<v8::Value> code(v8::Isolate* isolate) { \
Expand All @@ -62,6 +70,13 @@ namespace node {
#undef V

// Errors with predefined non-static messages
inline void THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(Environment* env,
int64_t timeout) {
std::ostringstream message;
message << "Script execution timed out after ";
message << timeout << "ms";
THROW_ERR_SCRIPT_EXECUTION_TIMEOUT(env, message.str().c_str());
}

inline v8::Local<v8::Value> ERR_BUFFER_TOO_LARGE(v8::Isolate *isolate) {
char message[128];
Expand Down
6 changes: 3 additions & 3 deletions test/parallel/test-repl-sigint-nested-eval.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,10 @@ child.stdout.once('data', common.mustCall(() => {
}));

child.on('close', function(code) {
assert.strictEqual(code, 0);
const expected = 'Script execution was interrupted by `SIGINT`';
assert.ok(
stdout.includes('Script execution interrupted.'),
`Expected stdout to contain "Script execution interrupted.", got ${stdout}`
stdout.includes(expected),
`Expected stdout to contain "${expected}", got ${stdout}`
);
assert.ok(
stdout.includes('foobar'),
Expand Down
5 changes: 3 additions & 2 deletions test/parallel/test-repl-sigint.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,10 @@ child.stdout.once('data', common.mustCall(() => {

child.on('close', function(code) {
assert.strictEqual(code, 0);
const expected = 'Script execution was interrupted by `SIGINT`';
assert.ok(
stdout.includes('Script execution interrupted.\n'),
`Expected stdout to contain "Script execution interrupted.", got ${stdout}`
stdout.includes(expected),
`Expected stdout to contain "${expected}", got ${stdout}`
);
assert.ok(
stdout.includes('42042\n'),
Expand Down
2 changes: 1 addition & 1 deletion test/parallel/test-repl-top-level-await.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ async function ctrlCTest() {
]), [
'await timeout(100000)\r',
'Thrown: Error [ERR_SCRIPT_EXECUTION_INTERRUPTED]: ' +
'Script execution was interrupted by `SIGINT`.',
'Script execution was interrupted by `SIGINT`',
PROMPT
]);
}
Expand Down
8 changes: 6 additions & 2 deletions test/parallel/test-vm-sigint-existing-handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,12 @@ if (process.argv[2] === 'child') {
[];
const options = { breakOnSigint: true };

assert.throws(() => { vm[method](script, ...args, options); },
/^Error: Script execution interrupted\.$/);
common.expectsError(
() => { vm[method](script, ...args, options); },
{
code: 'ERR_SCRIPT_EXECUTION_INTERRUPTED',
message: 'Script execution was interrupted by `SIGINT`'
});
assert.strictEqual(firstHandlerCalled, 0);
assert.strictEqual(onceHandlerCalled, 0);

Expand Down
8 changes: 6 additions & 2 deletions test/parallel/test-vm-sigint.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,12 @@ if (process.argv[2] === 'child') {
for (let i = 0; i < listeners; i++)
process.on('SIGINT', common.mustNotCall());

assert.throws(() => { vm[method](script, ...args, options); },
/^Error: Script execution interrupted\.$/);
common.expectsError(
() => { vm[method](script, ...args, options); },
{
code: 'ERR_SCRIPT_EXECUTION_INTERRUPTED',
message: 'Script execution was interrupted by `SIGINT`'
});
return;
}

Expand Down
59 changes: 37 additions & 22 deletions test/parallel/test-vm-timeout.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,35 +25,50 @@ const assert = require('assert');
const vm = require('vm');

// Timeout of 100ms executing endless loop
assert.throws(function() {
vm.runInThisContext('while(true) {}', { timeout: 100 });
}, /^Error: Script execution timed out\.$/);
assert.throws(
function() {
vm.runInThisContext('while(true) {}', { timeout: 100 });
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 100ms'
});

// Timeout of 1000ms, script finishes first
vm.runInThisContext('', { timeout: 1000 });

// Nested vm timeouts, inner timeout propagates out
assert.throws(function() {
const context = {
log: console.log,
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10)', context, { timeout: 10000 });
throw new Error('Test 5 failed');
}, /Script execution timed out\./);
assert.throws(
function() {
const context = {
log: console.log,
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10)', context, { timeout: 10000 });
throw new Error('Test 5 failed');
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 10ms'
});

// Nested vm timeouts, outer timeout is shorter and fires first.
assert.throws(function() {
const context = {
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10000)', context, { timeout: 100 });
throw new Error('Test 6 failed');
}, /Script execution timed out\./);
assert.throws(
function() {
const context = {
runInVM: function(timeout) {
vm.runInNewContext('while(true) {}', context, { timeout });
}
};
vm.runInNewContext('runInVM(10000)', context, { timeout: 100 });
throw new Error('Test 6 failed');
},
{
code: 'ERR_SCRIPT_EXECUTION_TIMEOUT',
message: 'Script execution timed out after 100ms'
});

// Nested vm timeouts, inner script throws an error.
assert.throws(function() {
Expand Down
2 changes: 1 addition & 1 deletion test/sequential/test-vm-timeout-rethrow.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,6 @@ if (process.argv[2] === 'child') {
});

process.on('exit', function() {
assert.ok(/Script execution timed out/.test(err));
assert.ok(/Script execution timed out after 1ms/.test(err));
});
}