It would be good to have error.prettyStack to capture same nice stack trace as console.error(..) does

# Igor Baklan (7 years ago)

It would be nice to have error.prettyStack and Execution.getPrettyStack() / Error.capturePrettyStackTrace(..) to capture same nice stack trace as console.error(..) does.

Generally problem with error.stack is that is is plain-text value, and it does not take into account source mapping. All this problems are solved in console.error(...) method. It prints nice stack trace with links to source files (including that, which provided by source mapping), but bad thing with it - that there is no standard API to capture it (in same nice form). So for me it looks like fair solution - to define some implementation-specific PrettyStack object/class with some basic methods like stk1.concat(stk2) and (Array/String -like) stk.slice(..). And say that PrettyStack internal structure is completely implementation-specific, but the only requirement is that it should be perfect compatibility between PrettyStack and console object. So that the following code snippet should produce 3 log messages with the same nice stack-trace included/printed:

console.error("error message with stack trace");
console.info("info message with stack trace", Execution.getPrettyStack());
console.debug("debug message with stack trace", new Error().prettyStack);

Main use case of this API is to facilitate some "home made" executable commands queue. In fact in this case you may want to see async-like stack-trace (where put-to-queue action stack-trace should be concatenated to command-execution stack-trace, and actually that concatenated async-like stack trace would be more informative then having just command-execution failure stack-trace alone).

In case if such pretty stack API exists, it would be possible to queue command-entry which includes current stack trace like queueAction: (_actionFunction_) -> {internal_queue.push({callerStack: Execution.getPrettyStack(), funcToRun: _actionFunction_})}. And in case if action from queue failed it would be possible to equip that failure with extra (async-like) stack-trace information, writing something like: err.asyncPrettyStack = err.prettyStack.concat(_queueEntry_.callerStack) (or more complete: if (err.asyncPrettyStack == null) {err.asyncPrettyStack = err.prettyStack}; err.asyncPrettyStack = err.asyncPrettyStack.concat(_queueEntry_.callerStack);).

Also it would be nice to have something like "base-stack-trace" ("context-stack-trace") which should be programmatically (freely) controlled by code, and automatically appended to current execution stack-trace (like it happens for async-like calls to ajax-api, setTimeout-api, etc). So that it may look like:

const runQueueEntry = function({callerStack: entryCallerPrettyStack, funcToRun: entryActionFunction}) {
  // so inside of entryActionFunction execution Execution.getPrettyStack() should be 
  // concatenation of entryCallerPrettyStack and actual current ("not-async") PrettyStack
  Execution.runWithContext({basePrettyStack: entryCallerPrettyStack}, entryActionFunction);
}
# Mark S. Miller (7 years ago)

some of these single-turn issues are addressed by

tc39.github.io/proposal-error-stacks, tc39/proposal-error-stacks

The stack object format there is derived from the Causeway debugger framework cocoonfx/causeway, www.hpl.hp.com/techreports/2009/HPL-2009-78.html which also provides additional instrumentation for inter-turn debugging.

Once the error-stacks proposal advances, we will make a separate proposal with the additional elements needed for inter-turn debugging. These are sufficiently distinct that they should be kept separate.

# Isiah Meadows (7 years ago)

You may be interested in this: tc39/proposal-error-stacks