Error diagnostics
An exception keeps its class across the op boundary: a TypeError thrown in Rust arrives in JavaScript as a TypeError, and a DOMException keeps its name, rather than both flattening to a string. A catch can therefore branch on the type, and the frames report the file, line and column the throw came from.
Stack traces
When an unhandled exception or unhandled promise rejection reaches the top level, esrun prints the class, the message and the frames, and exits non-zero:
TEXT
error: uncaught exception in my-script.mjs TypeError: network connection refused at fetchData (file:///path/to/script.mjs:10:5) at file:///path/to/script.mjs:2:1
Colour is conditional
The trace is coloured only when stderr is a terminal, so a piped or redirected run gets plain text. Setting NO_COLOR turns it off in either case.