error.stack includes the error message in some JS environments

Published on in JavaScript

Last updated on

In V8-based JS environments (e.g. Chrome, Deno and Node.js) and in Bun, error.stack = error class name + error.message + stack frames.

Table of contents

Context

I was logging an Error object's message and stack properties to Azure App Insights (because error.cause needs to be logged manually to App Insights), and was baffled because error.stack seemed to contain not only the stack trace, but also the error message. I thought App Insights was doing something wonky to the Error object.

Culprit: V8

Eventually I realized that that's how the V8 JS engine works. From V8's Stack trace API docs:

Here's an example of a fully formatted stack trace:

ReferenceError: FAIL is not defined
   at Constraint.execute (deltablue.js:525:2)
   at Constraint.recalculate (deltablue.js:424:21)
   at Planner.addPropagate (deltablue.js:701:6)
   at Constraint.satisfy (deltablue.js:184:15)
   at Planner.incrementalAdd (deltablue.js:591:21)
   at Constraint.addConstraint (deltablue.js:162:10)
   at Constraint.BinaryConstraint (deltablue.js:346:7)
   at Constraint.EqualityConstraint (deltablue.js:515:38)
   at chainTest (deltablue.js:807:6)
   at deltaBlue (deltablue.js:879:2)

Node.js's error.stack docs say it more explicitly:

The first line is formatted as <error class name>: <error message>, and is followed by a series of stack frames (each line beginning with "at ").

(It's mentioned in Node.js v4 docs as well. Node.js v4 was released in 2015.)

Non-V8 environments

In Firefox and Safari, error.stack contains only the stack trace. Firefox's JS engine is SpiderMonkey; Safari's JS engine is JavaScriptCore.

Bun is interesting because it's also "powered by JavaScriptCore", but its error.stack includes the error class name and error message as well.

Non-standard

The Error.prototype.stack page on MDN says that it's a non-standard property:

Non-standard: This feature is non-standard and is not on a standards track. Do not use it on production sites facing the Web: it will not work for every user. There may also be large incompatibilities between implementations and the behavior may change in the future.

Using error.stack on the server is likely a-okay though (as long as you are familiar with how it works in your JS environment).