Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crash when error.name is not a string #30572

Closed
griffinmyers opened this issue Nov 21, 2019 · 7 comments
Closed

Crash when error.name is not a string #30572

griffinmyers opened this issue Nov 21, 2019 · 7 comments
Labels
confirmed-bug Issues with confirmed bugs. util Issues and PRs related to the built-in util module.

Comments

@griffinmyers
Copy link

  • Version: v12.13.0.
  • Platform: Darwin will.local 18.7.0 Darwin Kernel Version 18.7.0: Sat Oct 12 00:02:19 PDT 2019; root:xnu-4903.278.12~1/RELEASE_X86_64 x86_64
  • Subsystem: internal/util/inspect.js

The following program crashes on node v12.13.0:

error-12.js
const err = new Error('bloop');
err.name = 404;
console.log(err);

with the following logged:

$ node error-12.js
internal/util/inspect.js:880
      name.endsWith('Error') &&
           ^

TypeError: name.endsWith is not a function
    at formatError (internal/util/inspect.js:880:12)
    at formatRaw (internal/util/inspect.js:681:14)
    at formatValue (internal/util/inspect.js:569:10)
    at inspect (internal/util/inspect.js:223:10)
    at formatWithOptions (internal/util/inspect.js:1651:40)
    at Object.Console.<computed> (internal/console/constructor.js:272:10)
    at Object.log (internal/console/constructor.js:282:61)
    at Object.<anonymous> (/Users/williammyers/projects/js/error-12.js:3:9)
    at Module._compile (internal/modules/cjs/loader.js:774:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:785:10)

On node v10.15.1, the program doesn't crash and instead logs:

$ node error-12.js
{ 404: bloop
    at Object.<anonymous> (/Users/williammyers/projects/js/error-12.js:1:75)
    at Module._compile (internal/modules/cjs/loader.js:689:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:700:10)
    at Module.load (internal/modules/cjs/loader.js:599:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:538:12)
    at Function.Module._load (internal/modules/cjs/loader.js:530:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:742:12)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:743:3) name: 404 }

I appreciate that node might not consider this a bug that is theirs to fix (the name property being non-string could be viewed as a userland error), but wanted to file the issue in case it was concerning.

I discovered this doing an upgrade to node 12--it turns out the official aws-sdk will set the name property of HTTP response errors to the numeric HTTP response code.

I suspect this was introduced in e54f237.

@Trott
Copy link
Member

Trott commented Nov 21, 2019

Seems like maybe inspect() can make sure to convert .name to a string before doing anything with it? Going to guess that this would be of interest to @BridgeAR.

@devsnek devsnek added the util Issues and PRs related to the built-in util module. label Nov 21, 2019
@griffinmyers
Copy link
Author

I should add, if the team thinks this is something node should patch, I'm more than happy to work up a PR.

@addaleax
Copy link
Member

I think it’s definitely something that Node.js should patch, so feel free to open a PR.

I also wonder why we have a .endsWith('Error') check in the first place – it’s not clear to me what exactly the code guarded by it does, but the check seems brittle and I wonder if there’s a better option?

You might also want to test the condition that .stack is not a string, I think it should fail similarly.

@BridgeAR
Copy link
Member

@addaleax

I wonder why we have a .endsWith('Error') check in the first place

The check identifies subclassed errors without direct own name property. The subclass name will then show up in the output. It tries to be very conservative by only visualizing the subclass name in case the errors name and stack have not been tampered with.

class SubError extends Error {}

console.log(new SubError('foo'))
// SubError: foo
//     at ...

// It will also highlight the actual name and the subclass name in case they are not aligned.
class FooBar extends Error{}

console.log(new FooBar('foo'))
// FooBar [Error]: foo
//     at ...

// Without this check both cases would be printed as:

// Error: foo
//     at ...

the check seems brittle and I wonder if there’s a better option?

Errors are pretty much the most difficult to inspect object type. They can have lots of shapes and it's quite difficult to always provide the best output (e.g., the stack property and the name and message could deviate from each other).
If someone finds a better way to get this right, that would be great!

griffinmyers pushed a commit to griffinmyers/aws-sdk-js that referenced this issue Nov 25, 2019
BridgeAR added a commit to BridgeAR/node that referenced this issue Nov 26, 2019
This makes sure that `util.inspect()` does not throw while inspecting
errors that have the name or stack property set to a different type
than string.

Fixes: nodejs#30572
@griffinmyers
Copy link
Author

Thank you, all, for the responsiveness and prompt followup!

targos pushed a commit that referenced this issue Dec 1, 2019
This makes sure that `util.inspect()` does not throw while inspecting
errors that have the name or stack property set to a different type
than string.

Fixes: #30572

PR-URL: #30576
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
@cuyl
Copy link

cuyl commented Dec 24, 2019

Any plan to ship the patch to v12?

@BridgeAR
Copy link
Member

@cuyl it should be published in one of the upcoming releases.

BethGriggs pushed a commit that referenced this issue Dec 27, 2019
This makes sure that `util.inspect()` does not throw while inspecting
errors that have the name or stack property set to a different type
than string.

Fixes: #30572

PR-URL: #30576
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
BethGriggs pushed a commit that referenced this issue Dec 31, 2019
This makes sure that `util.inspect()` does not throw while inspecting
errors that have the name or stack property set to a different type
than string.

Fixes: #30572

PR-URL: #30576
Reviewed-By: David Carlier <devnexen@gmail.com>
Reviewed-By: Anto Aravinth <anto.aravinth.cse@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
ckant added a commit to aws/aws-toolkit-vscode that referenced this issue Jun 5, 2020
- Add locking for (initial call to) GetChildren and (all calls to) LoadMoreChildren
Both of these append to the internal node cache
Any combination of these calls can possibly be in progress concurrently
The easiest (and probably most correct) behavior is to queue up calls behind a single write lock

- Ignore attempts to load more children when one is already in progress for the node
This can happen if the user double clicks the load more node
The intent was most likely to load a single page
Rather than queueing up 2 pages, it's better to drop the subsequent load command invocations

- Remove leading period from file extension filter
Per electron doc, the extension filter should not contain the leading period
Without this, Windows was shown to duplicate the file extension

- Tweak order of file extension filters
Was shown on mac that the first item will be the one selected by default

- Use hardcoded SVGs when the user has Seti file icon theme enabled
Indentation of child nodes gets messed up when the parent node doesn't have an icon
microsoft/vscode#85654

This is the case for the very common Seti file icon theme
Switching to SVG works around the issue for Seti

Other themes may also not have folder icons however there is no way
to detect this currently and the thought is that this is quite uncommon

The pros of using the native icon theme outweigh the cons here

- Clear the AWS SDK S3 bucket region cache before invocations
S3 maintains an internal cache of region to bucket name as an optimization
however this cache does not contain the partition

Bucket names are not unique across partitions

This can cause the wrong region to be selected when the
user switches between partitions that contain buckets with the same name

- Workaround logging errors when Error.name is a number
e.g. AWS SDK for JS can sometimes set the error name to the error code number (like 404)

Node.inspect (used by the logger) has a bug where it expects the name to be a string
and will actually throw an Error otherwise

VSCode's ES5 type definitions and lodash also make this expectation

The spec seems to make no mention of the string requirement

Additionally, Node fixed the Error in v12.14.1
nodejs/node#30572

However, VSCode uses an older version of Node without the fix
ckant added a commit to aws/aws-toolkit-vscode that referenced this issue Jun 6, 2020
- Add locking for (initial call to) GetChildren and (all calls to) LoadMoreChildren
Both of these append to the internal node cache
Any combination of these calls can possibly be in progress concurrently
The easiest (and probably most correct) behavior is to queue up calls behind a single write lock

- Ignore attempts to load more children when one is already in progress for the node
This can happen if the user double clicks the load more node
The intent was most likely to load a single page
Rather than queueing up 2 pages, it's better to drop the subsequent load command invocations

- Remove leading period from file extension filter
Per electron doc, the extension filter should not contain the leading period
Without this, Windows was shown to duplicate the file extension

- Tweak order of file extension filters
Was shown on mac that the first item will be the one selected by default

- Use hardcoded SVGs when the user has Seti file icon theme enabled
Indentation of child nodes gets messed up when the parent node doesn't have an icon
microsoft/vscode#85654

This is the case for the very common Seti file icon theme
Switching to SVG works around the issue for Seti

Other themes may also not have folder icons however there is no way
to detect this currently and the thought is that this is quite uncommon

The pros of using the native icon theme outweigh the cons here

- Clear the AWS SDK S3 bucket region cache before invocations
S3 maintains an internal cache of region to bucket name as an optimization
however this cache does not contain the partition

Bucket names are not unique across partitions

This can cause the wrong region to be selected when the
user switches between partitions that contain buckets with the same name

- Workaround logging errors when Error.name is a number
e.g. AWS SDK for JS can sometimes set the error name to the error code number (like 404)

Node.inspect (used by the logger) has a bug where it expects the name to be a string
and will actually throw an Error otherwise

VSCode's ES5 type definitions and lodash also make this expectation

The spec seems to make no mention of the string requirement

Additionally, Node fixed the Error in v12.14.1
nodejs/node#30572

However, VSCode uses an older version of Node without the fix
ckant added a commit to aws/aws-toolkit-vscode that referenced this issue Jul 22, 2020
- Add locking for (initial call to) GetChildren and (all calls to) LoadMoreChildren
Both of these append to the internal node cache
Any combination of these calls can possibly be in progress concurrently
The easiest (and probably most correct) behavior is to queue up calls behind a single write lock

- Ignore attempts to load more children when one is already in progress for the node
This can happen if the user double clicks the load more node
The intent was most likely to load a single page
Rather than queueing up 2 pages, it's better to drop the subsequent load command invocations

- Remove leading period from file extension filter
Per electron doc, the extension filter should not contain the leading period
Without this, Windows was shown to duplicate the file extension

- Tweak order of file extension filters
Was shown on mac that the first item will be the one selected by default

- Use hardcoded SVGs when the user has Seti file icon theme enabled
Indentation of child nodes gets messed up when the parent node doesn't have an icon
microsoft/vscode#85654

This is the case for the very common Seti file icon theme
Switching to SVG works around the issue for Seti

Other themes may also not have folder icons however there is no way
to detect this currently and the thought is that this is quite uncommon

The pros of using the native icon theme outweigh the cons here

- Clear the AWS SDK S3 bucket region cache before invocations
S3 maintains an internal cache of region to bucket name as an optimization
however this cache does not contain the partition

Bucket names are not unique across partitions

This can cause the wrong region to be selected when the
user switches between partitions that contain buckets with the same name

- Workaround logging errors when Error.name is a number
e.g. AWS SDK for JS can sometimes set the error name to the error code number (like 404)

Node.inspect (used by the logger) has a bug where it expects the name to be a string
and will actually throw an Error otherwise

VSCode's ES5 type definitions and lodash also make this expectation

The spec seems to make no mention of the string requirement

Additionally, Node fixed the Error in v12.14.1
nodejs/node#30572

However, VSCode uses an older version of Node without the fix
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug Issues with confirmed bugs. util Issues and PRs related to the built-in util module.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants