diff --git a/packages/cli-repl/src/cli-repl.spec.ts b/packages/cli-repl/src/cli-repl.spec.ts index 2d561a11dd..d5b6d2ab75 100644 --- a/packages/cli-repl/src/cli-repl.spec.ts +++ b/packages/cli-repl/src/cli-repl.spec.ts @@ -157,7 +157,7 @@ describe('CliRepl', () => { it('returns the list of available config options when asked to', () => { expect(cliRepl.listConfigOptions()).to.deep.equal([ - 'batchSize', 'enableTelemetry', 'inspectDepth', 'historyLength' + 'batchSize', 'enableTelemetry', 'inspectDepth', 'historyLength', 'showStackTraces' ]); }); diff --git a/packages/cli-repl/src/format-output.ts b/packages/cli-repl/src/format-output.ts index cfde3f8bf7..bdc57b8100 100644 --- a/packages/cli-repl/src/format-output.ts +++ b/packages/cli-repl/src/format-output.ts @@ -18,6 +18,7 @@ type FormatOptions = { depth?: number; maxArrayLength?: number; maxStringLength?: number; + showStackTraces?: boolean; }; /** @@ -167,6 +168,8 @@ export function formatError(error: Error, options: FormatOptions): string { } // leave a bit of breathing room after the syntax error message output result += '\n\n'; + } else if (options.showStackTraces && error.stack) { + result += error.stack.slice(error.stack.indexOf('\n')); } return result; diff --git a/packages/cli-repl/src/mongosh-repl.spec.ts b/packages/cli-repl/src/mongosh-repl.spec.ts index a3e3e4cd28..ab932cf9a8 100644 --- a/packages/cli-repl/src/mongosh-repl.spec.ts +++ b/packages/cli-repl/src/mongosh-repl.spec.ts @@ -463,6 +463,22 @@ describe('MongoshNodeRepl', () => { const { history } = mongoshRepl.runtimeState().repl as any; expect(history).to.have.lengthOf(2); }); + + it('controls stack trace display', async() => { + output = ''; + input.write('throw new Error("yellow")\n'); + await waitEval(bus); + expect(stripAnsi(output)).to.match(/Error: yellow\n(> )+$/); + + input.write('config.set("showStackTraces", true)\n'); + await waitEval(bus); + expect(output).to.include('Setting "showStackTraces" has been changed'); + + output = ''; + input.write('throw new Error("orange")\n'); + await waitEval(bus); + expect(stripAnsi(output)).to.match(/Error: orange\n +at\b/); + }); }); it('refreshes the prompt if a window resize occurs', async() => { diff --git a/packages/cli-repl/src/mongosh-repl.ts b/packages/cli-repl/src/mongosh-repl.ts index b5fca92bd2..54c6e74cb7 100644 --- a/packages/cli-repl/src/mongosh-repl.ts +++ b/packages/cli-repl/src/mongosh-repl.ts @@ -71,6 +71,7 @@ class MongoshNodeRepl implements EvaluationListener { insideAutoComplete: boolean; inspectDepth = 0; started = false; + showStackTraces = false; constructor(options: MongoshNodeReplOptions) { this.input = options.input; @@ -95,6 +96,7 @@ class MongoshNodeRepl implements EvaluationListener { await this.printStartupLog(internalState); this.inspectDepth = await this.getConfig('inspectDepth'); + this.showStackTraces = await this.getConfig('showStackTraces'); const repl = asyncRepl.start({ start: prettyRepl.start, @@ -414,12 +416,13 @@ class MongoshNodeRepl implements EvaluationListener { return clr(text, style, this.getFormatOptions()); } - getFormatOptions(): { colors: boolean, depth: number } { + getFormatOptions(): { colors: boolean, depth: number, showStackTraces: boolean } { const output = this.output as WriteStream; return { colors: this._runtimeState?.repl?.useColors ?? (output.isTTY && output.getColorDepth() > 1), - depth: this.inspectDepth + depth: this.inspectDepth, + showStackTraces: this.showStackTraces }; } @@ -458,6 +461,9 @@ class MongoshNodeRepl implements EvaluationListener { if (key === 'inspectDepth') { this.inspectDepth = +value; } + if (key === 'showStackTraces') { + this.showStackTraces = !!value; + } return this.ioProvider.setConfig(key, value); } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 92688b8f06..622db8aa34 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -116,6 +116,7 @@ export class CliUserConfig extends ShellUserConfig { disableGreetingMessage = false; inspectDepth = 6; historyLength = 1000; + showStackTraces = false; } export interface ConfigProvider {