Today I encountered some behavior that really threw me for a loop while debugging, because at first I really didn't understand what I was looking at. After a lot of trial and error I came to understand that console.dir
has some unusual behavior with Error
objects, and I'd like to understand it better.
If you open the Chrome developer console and run console.dir({a: 1, b: 2})
, you'll see an expandable Object, like so:
Expanding the dropdown shows the properties a
and b
, plus their values, as expected. On a Promise, the results are similar, although notably the word Object
is replaced by Promise
:
However, with an Error, the results are different:
Notice now it prints a stacktrace. If you didn't know any better, you'd think you had just printed a string, and you might expect that dropdown arrow to show you more lines of the stacktrace. Of course, instead the dropdown shows you the properties on the object.
But notice that toString
gives something else, it gives the message but without the stack. If you expand the dropdown, what you see are these properties:
So it looks like console.dir
is printing out the Error's stack
property. But why? If error.toString()
prints the message
property, then why does console.dir
instead show the value of the stack
property, which of course only exists on Error objects? Is console.dir
hard-coded to treat errors differently than other object classes?
Likewise, Promise().resolve().toString()
gives [object Promise]
-- so where is console.dir
getting the Promise
string from when you run console.dir
on a Promise? The behavior here is just unclear and I feel like I might learn something about the internals of something if I get a clearer understanding of this behavior.