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

build(lint): throw error when number of extra args doesn't match the number of format specifiers in logger. #5895

Merged
merged 28 commits into from
Nov 7, 2024

Conversation

Hweinstock
Copy link
Contributor

@Hweinstock Hweinstock commented Oct 29, 2024

Builds off of:
#5878

Problem

currently logger.error(msg, err) silently drops err if it doesn't map to a %x format specifier in msg.
we want to either prevent that mistake, or enhance our logger so that it prints useful parts of err instead of silently dropping it.

Also, there are cases like:
getLogger().error('Certificate path {0} already exists', certPath), but this silently drops the arg certPath. Pretty sure this syntax is from Java IIRC and not supported by Node.

Solution

Provide a custom lint rule to ensure the number of extra args matches the number of format specifiers.

Note About Alternatives

  • As an alternative, we could have transformed the extra meta items to strings and appended them to the log message or add them as separate log messages. This would allow usage of the form getLogger().error('hit error', e).
  • If we add separate log messages, we break the expectation that each logger.error statement corresponds to one message in the log.
  • Conversely, if we append to the log message, this is somewhat of a hidden feature not exposed to the consumer. By forcing them to add a '%O' format specifier, we are making them clearly aware of how the error (or other object) will show up in the log, ensuring the effect does not "surprise" the user.

Notes

Relevant: code used to format errors:

export function formatError(err: Error): string {
const code = hasCode(err) && err.code !== err.name ? `[${err.code}]` : undefined
const parts = [`${err.name}:`, getErrorMsg(err), code, formatDetails(err)]
return parts.filter(isNonNullable).join(' ')
}

which should now actually be used since errors won't be dropped.

  • JSCPD is failing due to some duplicates in the files touched. (none introduced here).

License: I confirm that my contribution is made under the terms of the Apache 2.0 license.

@Hweinstock Hweinstock marked this pull request as ready for review November 5, 2024 20:40
@Hweinstock Hweinstock requested review from a team as code owners November 5, 2024 20:40
Copy link
Contributor

@jpinkney-aws jpinkney-aws left a comment

Choose a reason for hiding this comment

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

It looks like theres a couple more linting that fail at the bottom of this PR as well

packages/core/src/lambda/commands/deploySamApplication.ts Outdated Show resolved Hide resolved
@@ -78,7 +78,7 @@ describe('samProject', () => {
// simulate error when no samconfig.toml file in directory
const result = await getStackName(projectRoot)
assert.deepStrictEqual(result, {})
assertLogsContain('No stack name or region information available in samconfig.toml', true, 'info')
assertLogsContain('No stack name or region information available in samconfig.toml: %O', true, 'info')
Copy link
Contributor

Choose a reason for hiding this comment

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

Does the log literally contain a "%O" string? If so, that seems like a bug.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, but believe it is only because we are in the TestLogger, which adds the raw strings to an array. (https://github.com/aws/aws-toolkit-vscode/blob/b2ebc10342f63ac95cd3055393e715cb369ec450/packages/core/src/test/testLogger.ts)

@justinmk3 justinmk3 merged commit 4add487 into aws:master Nov 7, 2024
21 of 25 checks passed
@Hweinstock Hweinstock deleted the lint/noStringSubDrop branch November 8, 2024 13:52
justinmk3 pushed a commit that referenced this pull request Nov 22, 2024
## Problem
The test logger does not format additional arguements into the logs in
the same way as ToolkitLogger.
Ex. `getLogger().debug('here is the obj: %O', obj)` will produce two
`LogEntries` one with `"here is the obj: %O"` and one with the object
itself.

This is problematic because it causes confusion (see:
#5895 (comment))
and it also can cause `assertLogsContain` to throw an error since there
is now a non-string/error entry in the log entry list (see:
https://github.com/aws/aws-toolkit-vscode/blob/338ea67f2ba0294fc535a9a949fd1cdaeaa96d98/packages/core/src/test/globalSetup.test.ts#L171-L185).

## Solution
- Have test logger inherit from `BaseLogger` to minimize implementation
dupe.
- If we see a string, format it with extra inputs before pushing it into
entries.
- Add tests for the `testLogger`. 
- Adjust existing tests that relied on this behavior. 
- If on web, we simply concat the strings to avoid reimplementing
`util.format`:
https://github.com/nodejs/node/blob/3178a762d6a2b1a37b74f02266eea0f3d86603be/lib/internal/util/inspect.js#L2191-L2315

---

<!--- REMINDER: Ensure that your PR meets the guidelines in
CONTRIBUTING.md -->

License: I confirm that my contribution is made under the terms of the
Apache 2.0 license.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants