8000
We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
There was an error while loading. Please reload this page.
1 parent 71bb6cd commit 1a44265Copy full SHA for 1a44265
lib/repl.js
@@ -1837,7 +1837,7 @@ function includesProxiesOrGetters(expr, exprStr, evalFn, ctx, callback) {
1837
if (astProp.type === 'Literal') {
1838
// We have something like `obj['foo'].x` where `x` is the literal
1839
1840
- if (isProxy(obj[astProp.value])) {
+ if (safeIsProxyAccess(obj, astProp.value)) {
1841
return cb(true);
1842
}
1843
@@ -1855,7 +1855,7 @@ function includesProxiesOrGetters(expr, exprStr, evalFn, ctx, callback) {
1855
) {
1856
// We have something like `obj.foo.x` where `foo` is the identifier
1857
1858
- if (isProxy(obj[astProp.name])) {
+ if (safeIsProxyAccess(obj, astProp.name)) {
1859
1860
1861
@@ -1882,7 +1882,7 @@ function includesProxiesOrGetters(expr, exprStr, evalFn, ctx, callback) {
1882
1883
1884
if (typeof evaledProp === 'string') {
1885
- if (isProxy(obj[evaledProp])) {
+ if (safeIsProxyAccess(obj, evaledProp)) {
1886
1887
1888
@@ -1899,6 +1899,15 @@ function includesProxiesOrGetters(expr, exprStr, evalFn, ctx, callback) {
1899
);
1900
1901
1902
+ function safeIsProxyAccess(obj, prop) {
1903
+ // Accessing `prop` may trigger a getter that throws, so we use try-catch to guard against it
1904
+ try {
1905
+ return isProxy(obj[prop]);
1906
+ } catch {
1907
+ return false;
1908
+ }
1909
1910
+
1911
return callback(false);
1912
1913
test/parallel/test-repl-tab-complete-getter-error.js
@@ -0,0 +1,51 @@
1
+'use strict';
2
3
+const common = require('../common');
4
+const repl = require('repl');
5
+const ArrayStream = require('../common/arraystream');
6
+const assert = require('assert');
7
8
+(async function() {
9
+ await runTest();
10
+})().then(common.mustCall());
11
12
+async function runTest() {
13
+ const input = new ArrayStream();
14
+ const output = new ArrayStream();
15
16
+ const replServer = repl.start({
17
+ prompt: '',
18
+ input,
19
+ output: output,
20
+ allowBlockingCompletions: true,
21
+ terminal: true
22
+ });
23
24
+ replServer._domain.on('error', (e) => {
25
+ assert.fail(`Error in REPL domain: ${e}`);
26
27
28
+ await new Promise((resolve, reject) => {
29
+ replServer.eval(`
30
+ const getNameText = () => "name";
31
+ const foo = { get name() { throw new Error(); } };
32
+ `, replServer.context, '', (err) => {
33
+ if (err) {
34
+ reject(err);
35
+ } else {
36
+ resolve();
37
38
39
40
41
+ ['foo.name.', 'foo["name"].', 'foo[getNameText()].'].forEach((test) => {
42
+ replServer.complete(
43
+ test,
44
+ common.mustCall((error, data) => {
45
+ assert.strictEqual(error, null);
46
+ assert.strictEqual(data.length, 2);
47
+ assert.strictEqual(data[1], test);
48
+ })
49
+ );
50
51
+}