denoland / deno

A modern runtime for JavaScript and TypeScript.
https://deno.com
MIT License
96.07k stars 5.31k forks source link

Built-in error prototypes are printed as "undefined" through Deno.inspect/console.log #12925

Open ghost opened 2 years ago

ghost commented 2 years ago

All of the built-in error classes, besides Error, have prototype objects that show as "undefined" when logged, yet they're not actually undefined!

Example test code:

console.log(
  [
    Error,
    EvalError,
    RangeError,
    ReferenceError,
    SyntaxError,
    TypeError,
    URIError,
    AggregateError,
  ].map((ErrorClass) => ErrorClass.prototype),
);

Yet, observe that they're objects:

console.log(
  [
    Error,
    EvalError,
    RangeError,
    ReferenceError,
    SyntaxError,
    TypeError,
    URIError,
    AggregateError,
  ].map((ErrorClass) => typeof ErrorClass.prototype),
);

Very misleading, and threw me off while messing with the error prototypes :sweat_smile:

andreubotella commented 2 years ago

This seems to happen because TypeError.prototype instanceof Error returns true (and in general, SubClass.prototype instanceof ParentClass – this is not a bug, it's how JS works). This leads to the prototypes of native errors being treated as if they were errors in our console implementation:

https://github.com/denoland/deno/blob/3881e2e7bf3bbe4a5d62872a9fb7b6e2e3d82f81/ext/console/02_console.js#L1163-L1164

And inspectError prints the error's stack property followed by any causes, but the prototypes of native errors don't have a stack property, so it's undefined that gets printed.

andreubotella commented 2 years ago

Here's how the different browsers log the native error prototypes:

`TypeError.prototype` in the DevTools console for different browsers. Chrome: `Error {name: 'TypeError', message: '', constructor: f}`. Firefox: `TypeError.prototype { stack: "", ... }`. Epiphany (WebKit): `TypeError {name: "TypeError", message: ""}`

For regular errors, Chrome prints the stack, but for native error prototypes it seems to log them as error objects. The other browser engines do something specific to the native error prototypes.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions.