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

feat: drop internal functions from Deprecation Error stack trace #3426

Merged
merged 14 commits into from
Mar 29, 2022

Conversation

yuth
Copy link
Contributor

@yuth yuth commented Mar 15, 2022

JSII can throw Deprecation Error and fail compilation when a deprecated property,
enum or method is being used when JSII_DEPRECATED environment variable is set
to fail. The deprecation error is throw from .warnings.jsii.js generated file.
When nested prop of enum is deprecated, the stack trace will contain lot of methods
from .warnings.jsii.js and since the file is minimized, tools like Jest which try to be
helpful by printing the line where the error is thrown shows a wall of text without much useful information.


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

JSII can throw Deprecation Error and fail compilation when a deprecated property,
enum or method is being used when `JSII_DEPRECATED` environment variable is set
to `fail`. The deprecation error is throw from `.warnings.jsii.js` generated file.
When nested prop of enum is deprecated, the stack trace will contain lot of methods
from `.warnings.jsii.js` and since the file is minimized, tools like Jest which try to be
helpful by printing the line where the error is thrown shows a wall of text without much useful
information.

With this change, the Deprecation error is caught and rethrown from top level class which
call the validator to provide a clean stack trace. This approch is taken instead of passing the
call site to deprecation handler as we can't get call site for setters and  getters that can be
used by `Error.captureStack`
@mergify mergify bot added the contribution/core This is a PR that came from AWS. label Mar 15, 2022
@RomainMuller RomainMuller force-pushed the jsii-deprecation-error-code branch from 0888e83 to 41d2fe9 Compare March 28, 2022 22:45
try {
vm.runInContext(source, context, { filename: 'index.js' });
// The above line should have resulted in a DeprecationError being thrown
expect(null).toBeInstanceOf(Error);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if I understand this line? Is the intention here to intentionally fail the test? Maybe something like this could make it clearer:

Suggested change
expect(null).toBeInstanceOf(Error);
throw new Error("expected a DeprecationError from running the transliterated snippet")

Or maybe "expect(true).toEqual(false)"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The expect(null) check guarantees that the test will be marked as failed if no exception was thrown. If we move to the throw style, it'll trigger the catch and will happily update the snapshot when running with -u, which I think is not desirable behavior.

I kind of agree with your sentiment here, but this "hack" is just a bit safer.

Ideally - I'd have wanted to do expect(() => vm.runInContext(...)).toThrow, but that'll only verify the error message, not the stack trace (which is what I care about here).

// this emulates the situation that would be if the file had been through a
// bundler by turning all sequences of white spaces (new line included) into
// single spaces.
require: (id: string) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a better way?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's the sort of dance you have to do when you use VM contexts in node. The context keys are global values that'll be available within the sandbox; which otherwise only has access to ES primordials... So you need to give it "a" require function, and that function is a pretty standard implementation here...

All those APIs are stable enough that they won't break under us when we upgrade to a new node version, too.

@mergify
Copy link
Contributor

mergify bot commented Mar 29, 2022

Thank you for contributing! ❤️ I will now look into making sure the PR is up-to-date, then proceed to try and merge it!

@mergify mergify bot added the pr/ready-to-merge This PR is ready to be merged. label Mar 29, 2022
@mergify
Copy link
Contributor

mergify bot commented Mar 29, 2022

Merging (with squash)...

@mergify mergify bot merged commit 5b4b852 into aws:main Mar 29, 2022
@mergify
Copy link
Contributor

mergify bot commented Mar 29, 2022

Merging (with squash)...

@mergify mergify bot removed the pr/ready-to-merge This PR is ready to be merged. label Mar 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
contribution/core This is a PR that came from AWS.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants