diff --git a/packages/core/src/lib/Console.ts b/packages/core/src/lib/Console.ts index bcab4817..4f66c5ee 100644 --- a/packages/core/src/lib/Console.ts +++ b/packages/core/src/lib/Console.ts @@ -16,7 +16,13 @@ import path from 'path'; import readline from 'readline'; import stringWidth from 'string-width'; import {OutputFormat, type MemLabConfig} from './Config'; -import {AnyValue, Nullable, Optional} from './Types'; +import { + AnyValue, + ConsoleOutputAnnotation, + ConsoleOutputOptions, + Nullable, + Optional, +} from './Types'; type Message = { lines: number[]; @@ -117,6 +123,9 @@ class MemLabConsole { }; private static singleton: MemLabConsole; + public annotations: {[key: string]: ConsoleOutputAnnotation} = { + STACK_TRACE: 'stack-trace', + }; protected constructor() { this.sections = { @@ -442,13 +451,18 @@ class MemLabConsole { this.printStr(this.style(msg, 'mid')); } - public lowLevel(msg: string): void { + public lowLevel(msg: string, options: ConsoleOutputOptions = {}): void { if (this.shouldBeConcise('lowLevel')) { return this.overwrite(msg); } this.logMsg(msg); if (this.config.muteConfig?.muteLowLevel) { - return; + if ( + options.annotation !== this.annotations.STACK_TRACE || + this.config.muteConfig?.muteError + ) { + return; + } } this.clearPrevOverwriteMsg(); this.printStr(this.style(msg, 'low')); diff --git a/packages/core/src/lib/Types.ts b/packages/core/src/lib/Types.ts index ba8a2795..b7c69283 100644 --- a/packages/core/src/lib/Types.ts +++ b/packages/core/src/lib/Types.ts @@ -2446,3 +2446,11 @@ export type JSONifyOptions = { forceJSONifyDepth?: number; serializationHelper?: ISerializationHelper; }; + +/** @internal */ +export type ConsoleOutputAnnotation = 'stack-trace'; + +/** @internal */ +export type ConsoleOutputOptions = { + annotation?: ConsoleOutputAnnotation; +}; diff --git a/packages/core/src/lib/Utils.ts b/packages/core/src/lib/Utils.ts index 7aed3873..776d986c 100644 --- a/packages/core/src/lib/Utils.ts +++ b/packages/core/src/lib/Utils.ts @@ -1300,7 +1300,9 @@ function callAsync(f: AnyAyncFunction): void { promise.catch((e: unknown) => { const parsedError = getError(e); info.error(parsedError.message); - info.lowLevel(parsedError.stack ?? ''); + info.lowLevel(parsedError.stack ?? '', { + annotation: info.annotations.STACK_TRACE, + }); }); } } @@ -1892,7 +1894,9 @@ function haltOrThrow( } // only print stack trace in verbose mode if (config.verbose) { - info.lowLevel(err.stack ?? ''); + info.lowLevel(err.stack ?? '', { + annotation: info.annotations.STACK_TRACE, + }); } else { info.topLevel( 'Use `memlab help` or `memlab -h` to get helper text', @@ -2036,7 +2040,9 @@ export function runShell( if (config.verbose || config.isContinuousTest) { if (ex instanceof Error) { info.lowLevel(ex.message); - info.lowLevel(ex.stack ?? ''); + info.lowLevel(ex.stack ?? '', { + annotation: info.annotations.STACK_TRACE, + }); } } if (options.throwError) {