diff --git a/doc/api/errors.md b/doc/api/errors.md
index 1cf926c84be4a2..80b5f44bc59cbe 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -1224,6 +1224,13 @@ time.
The `--input-type` flag was used to attempt to execute a file. This flag can
only be used with input via `--eval`, `--print` or `STDIN`.
+
+### `ERR_INSPECTOR_ALREADY_ACTIVATED`
+
+While using the `inspector` module, an attempt was made to activate the
+inspector when it already started to listen on a port. Use `inspector.close()`
+before activating it on a different address.
+
### `ERR_INSPECTOR_ALREADY_CONNECTED`
diff --git a/lib/inspector.js b/lib/inspector.js
index 269f95dbd27a12..60640bc1fb6456 100644
--- a/lib/inspector.js
+++ b/lib/inspector.js
@@ -8,6 +8,7 @@ const {
} = primordials;
const {
+ ERR_INSPECTOR_ALREADY_ACTIVATED,
ERR_INSPECTOR_ALREADY_CONNECTED,
ERR_INSPECTOR_CLOSED,
ERR_INSPECTOR_COMMAND,
@@ -33,6 +34,7 @@ const {
MainThreadConnection,
open,
url,
+ isEnabled,
waitForDebugger
} = internalBinding('inspector');
@@ -131,6 +133,9 @@ class Session extends EventEmitter {
}
function inspectorOpen(port, host, wait) {
+ if (isEnabled()) {
+ throw new ERR_INSPECTOR_ALREADY_ACTIVATED();
+ }
open(port, host);
if (wait)
waitForDebugger();
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 6640f7597c8128..8bd39eaaad082f 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -941,6 +941,10 @@ E('ERR_INCOMPATIBLE_OPTION_PAIR',
'Option "%s" cannot be used in combination with option "%s"', TypeError);
E('ERR_INPUT_TYPE_NOT_ALLOWED', '--input-type can only be used with string ' +
'input via --eval, --print, or STDIN', Error);
+E('ERR_INSPECTOR_ALREADY_ACTIVATED',
+ 'Inspector is already activated. Close it with inspector.close() ' +
+ 'before activating it again.',
+ Error);
E('ERR_INSPECTOR_ALREADY_CONNECTED', '%s is already connected', Error);
E('ERR_INSPECTOR_CLOSED', 'Session was closed', Error);
E('ERR_INSPECTOR_COMMAND', 'Inspector error %d: %s', Error);
diff --git a/test/sequential/test-inspector-already-activated-cli.js b/test/sequential/test-inspector-already-activated-cli.js
new file mode 100644
index 00000000000000..ba76d5168c14b9
--- /dev/null
+++ b/test/sequential/test-inspector-already-activated-cli.js
@@ -0,0 +1,19 @@
+// Flags: --inspect=0
+'use strict';
+
+const common = require('../common');
+common.skipIfInspectorDisabled();
+common.skipIfWorker();
+
+const assert = require('assert');
+const inspector = require('inspector');
+const wsUrl = inspector.url();
+assert(wsUrl.startsWith('ws://'));
+assert.throws(() => {
+ inspector.open(0, undefined, false);
+}, {
+ code: 'ERR_INSPECTOR_ALREADY_ACTIVATED'
+});
+assert.strictEqual(inspector.url(), wsUrl);
+inspector.close();
+assert.strictEqual(inspector.url(), undefined);
diff --git a/test/sequential/test-inspector-open.js b/test/sequential/test-inspector-open.js
index 967ebe49bfb764..190a99e7282e52 100644
--- a/test/sequential/test-inspector-open.js
+++ b/test/sequential/test-inspector-open.js
@@ -10,6 +10,10 @@ const fork = require('child_process').fork;
const net = require('net');
const url = require('url');
+const kFirstOpen = 0;
+const kOpenWhileOpen = 1;
+const kReOpen = 2;
+
if (process.env.BE_CHILD)
return beChild();
@@ -19,7 +23,7 @@ const child = fork(__filename,
child.once('message', common.mustCall((msg) => {
assert.strictEqual(msg.cmd, 'started');
- child.send({ cmd: 'open', args: [0] });
+ child.send({ cmd: 'open', args: [kFirstOpen] });
child.once('message', common.mustCall(firstOpen));
}));
@@ -31,7 +35,7 @@ function firstOpen(msg) {
ping(port, (err) => {
assert.ifError(err);
// Inspector is already open, and won't be reopened, so args don't matter.
- child.send({ cmd: 'open', args: [] });
+ child.send({ cmd: 'open', args: [kOpenWhileOpen] });
child.once('message', common.mustCall(tryToOpenWhenOpen));
firstPort = port;
});
@@ -62,7 +66,7 @@ function closeWhenOpen(msg) {
function tryToCloseWhenClosed(msg) {
assert.strictEqual(msg.cmd, 'url');
assert.strictEqual(msg.url, undefined);
- child.send({ cmd: 'open', args: [] });
+ child.send({ cmd: 'open', args: [kReOpen] });
child.once('message', common.mustCall(reopenAfterClose));
}
@@ -93,7 +97,17 @@ function beChild() {
process.on('message', (msg) => {
if (msg.cmd === 'open') {
- inspector.open(...msg.args);
+ if (msg.args[0] === kFirstOpen) {
+ inspector.open(0, false, undefined);
+ } else if (msg.args[0] === kOpenWhileOpen) {
+ assert.throws(() => {
+ inspector.open(0, false, undefined);
+ }, {
+ code: 'ERR_INSPECTOR_ALREADY_ACTIVATED'
+ });
+ } else if (msg.args[0] === kReOpen) {
+ inspector.open(0, false, undefined);
+ }
}
if (msg.cmd === 'close') {
inspector.close();