refactor(@embark/core/console): silence errors when autocomplete is attempted on bad reference

Previously, in the embark cli dashboard/console, if you were to type `Foo.` and
hit tab for autocomplete then (assuming you hadn't defined `Foo`) there would
be unhandled errors and the console could even become unusable.

Refactor `packages/core/console` and related code so that nothing happens when
you attempt to autocomplete a bad reference (the same behavior as Node's own
REPL).
This commit is contained in:
Michael Bradley, Jr 2019-10-31 18:48:06 -05:00 committed by Michael Bradley
parent 6b405d1d7e
commit c320dcfbb5
3 changed files with 35 additions and 18 deletions

View File

@ -52,7 +52,7 @@ class CodeRunner {
this.vm.registerVar(varName, code, cb); this.vm.registerVar(varName, code, cb);
} }
private evalCode(code: string, cb: Callback<any>, tolerateError = false) { private evalCode(code: string, cb: Callback<any>, tolerateError = false, logCode = true, logError = true) {
cb = cb || (() => { }); cb = cb || (() => { });
if (!code) { if (!code) {
@ -61,8 +61,12 @@ class CodeRunner {
this.vm.doEval(code, tolerateError, (err, result) => { this.vm.doEval(code, tolerateError, (err, result) => {
if (err) { if (err) {
this.logger.error(__("Error running code: %s", code)); if (logCode) {
this.logger.error(err.toString()); this.logger.error(__("Error running code: %s", code));
}
if (logError) {
this.logger.error(err.toString());
}
return cb(err); return cb(err);
} }

View File

@ -47,13 +47,18 @@ class Console {
if (this.ipc.isServer()) { if (this.ipc.isServer()) {
this.ipc.on("console:executeCmd", (cmd: string, cb: any) => { this.ipc.on("console:executeCmd", (cmd: string, cb: any) => {
this.executeCmd(cmd, (err: string, result: any) => { this.executeCmd(cmd, (err: any, result: any) => {
let error = null;
if (err) { if (err) {
// reformat for IPC reply // reformat for IPC reply
error = { name: "Console error", message: err, stack: err }; err = { name: "Console error", message: err, stack: err.stack };
return cb(err);
} }
cb(error, util.inspect(result)); cb(null, util.inspect(result));
});
});
this.ipc.on("console:executePartial", (cmd: string, cb: any) => {
this.executePartial(cmd, (_: any, result: any) => {
cb(null, util.inspect(result));
}); });
}); });
this.ipc.on("console:history:save", true, (cmd: string) => { this.ipc.on("console:history:save", true, (cmd: string) => {
@ -70,6 +75,7 @@ class Console {
if (cb) { cb(); } if (cb) { cb(); }
}); });
this.events.setCommandHandler("console:executeCmd", this.executeCmd.bind(this)); this.events.setCommandHandler("console:executeCmd", this.executeCmd.bind(this));
this.events.setCommandHandler("console:executePartial", this.executePartial.bind(this));
this.events.setCommandHandler("console:history", (cb: any) => this.getHistory(this.cmdHistorySize(), cb)); this.events.setCommandHandler("console:history", (cb: any) => this.getHistory(this.cmdHistorySize(), cb));
this.registerConsoleCommands(); this.registerConsoleCommands();
@ -149,7 +155,19 @@ class Console {
return false; return false;
} }
private executeCmd(cmd: string, callback: any) { private executePartial(cmd: string, callback: any) {
// if this is the embark console process, send the command to the process
// running all the needed services (ie the process running `embark run`)
if (this.isEmbarkConsole) {
return this.ipc.request("console:executePartial", cmd, callback);
}
this.executeCmd(cmd, (_: any, result: any) => {
callback(null, result);
});
}
private executeCmd(cmd: string, callback?: any, logEvalCode = false, logEvalError = false) {
// if this is the embark console process, send the command to the process // if this is the embark console process, send the command to the process
// running all the needed services (ie the process running `embark run`) // running all the needed services (ie the process running `embark run`)
if (this.isEmbarkConsole) { if (this.isEmbarkConsole) {
@ -197,12 +215,7 @@ class Console {
return callback(null, output); return callback(null, output);
} }
this.events.request("runcode:eval", cmd, (err: Error, result: any) => { this.events.request("runcode:eval", cmd, callback, true, logEvalCode, logEvalError);
if (err) {
return callback(err.message);
}
callback(null, result);
}, true);
} }
private registerConsoleCommands() { private registerConsoleCommands() {

View File

@ -27,7 +27,7 @@ class REPL {
this.events.request('console:executeCmd', cmd.trim(), function (err, message) { this.events.request('console:executeCmd', cmd.trim(), function (err, message) {
if (err) { if (err) {
// Do not return as the first param (error), because the dashboard doesn't print errors // Do not return as the first param (error), because the dashboard doesn't print errors
return callback(null, err.red); return callback(null, err.message ? err.message.red : err.red);
} }
callback(null, message === undefined ? '' : message); // This way, we don't print undefined callback(null, message === undefined ? '' : message); // This way, we don't print undefined
}); });
@ -58,9 +58,9 @@ class REPL {
hint = partial; hint = partial;
} }
this.events.request('console:executeCmd', context, (err, result) => { this.events.request('console:executePartial', context, (err, result) => {
if (err !== null) { if (err || !result) {
cb(err, [[], partial]); return cb(null, [[], partial]);
} }
let props = Object let props = Object