diff --git a/doc/api/errors.md b/doc/api/errors.md
index df81718e7d7fb0..ff317f676a8881 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -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.
+
### ERR_SERVER_ALREADY_LISTEN
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 09f58506c44ea0..e7eb3bd133813a 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -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);
diff --git a/src/module_wrap.cc b/src/module_wrap.cc
index 9bcdb4dce75ff2..f88c113ae0b93f 100644
--- a/src/module_wrap.cc
+++ b/src/module_wrap.cc
@@ -286,9 +286,9 @@ void ModuleWrap::Evaluate(const FunctionCallbackInfo& 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);
}
}
diff --git a/src/node_contextify.cc b/src/node_contextify.cc
index e07d5ebcd29d0d..ca58d1897e68b2 100644
--- a/src/node_contextify.cc
+++ b/src/node_contextify.cc
@@ -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"
@@ -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);
}
}
diff --git a/src/node_errors.h b/src/node_errors.h
index 0f91872474148d..eb120c62807cf6 100644
--- a/src/node_errors.h
+++ b/src/node_errors.h
@@ -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
+
namespace node {
// Helpers to construct errors similar to the ones provided by
@@ -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)
@@ -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 code(v8::Isolate* isolate) { \
@@ -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 ERR_BUFFER_TOO_LARGE(v8::Isolate *isolate) {
char message[128];
diff --git a/test/parallel/test-repl-sigint-nested-eval.js b/test/parallel/test-repl-sigint-nested-eval.js
index 7f15b7dfeb8b9d..ea07393527b828 100644
--- a/test/parallel/test-repl-sigint-nested-eval.js
+++ b/test/parallel/test-repl-sigint-nested-eval.js
@@ -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'),
diff --git a/test/parallel/test-repl-sigint.js b/test/parallel/test-repl-sigint.js
index 818111c39bf578..14cafd0463709f 100644
--- a/test/parallel/test-repl-sigint.js
+++ b/test/parallel/test-repl-sigint.js
@@ -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'),
diff --git a/test/parallel/test-repl-top-level-await.js b/test/parallel/test-repl-top-level-await.js
index 91f5758c210a36..5a07f5ced14450 100644
--- a/test/parallel/test-repl-top-level-await.js
+++ b/test/parallel/test-repl-top-level-await.js
@@ -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
]);
}
diff --git a/test/parallel/test-vm-sigint-existing-handler.js b/test/parallel/test-vm-sigint-existing-handler.js
index 79a4d556ac05d6..13fccd9637c7fb 100644
--- a/test/parallel/test-vm-sigint-existing-handler.js
+++ b/test/parallel/test-vm-sigint-existing-handler.js
@@ -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);
diff --git a/test/parallel/test-vm-sigint.js b/test/parallel/test-vm-sigint.js
index 9935b3d04b57a8..0fecfbace68049 100644
--- a/test/parallel/test-vm-sigint.js
+++ b/test/parallel/test-vm-sigint.js
@@ -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;
}
diff --git a/test/parallel/test-vm-timeout.js b/test/parallel/test-vm-timeout.js
index 859992e99ba36f..426d1e06925514 100644
--- a/test/parallel/test-vm-timeout.js
+++ b/test/parallel/test-vm-timeout.js
@@ -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() {
diff --git a/test/sequential/test-vm-timeout-rethrow.js b/test/sequential/test-vm-timeout-rethrow.js
index a7aa83e513d03c..c38460c4c89925 100644
--- a/test/sequential/test-vm-timeout-rethrow.js
+++ b/test/sequential/test-vm-timeout-rethrow.js
@@ -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));
});
}