Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Add goroutinemissingrecover linter: flag panic-unsafe goroutines #48966
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
Uh oh!
There was an error while loading. Please reload this page.
Add goroutinemissingrecover linter: flag panic-unsafe goroutines #48966
Changes from all commits
5deb90cda9d56a286acdbc8a8423bc037aeb92a5b3File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
There are no files selected for viewing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unbounded
ast.Inspectdescends into nested function literals, causing false negatives for the exact bug class this linter exists to catch.💡 Details
Go semantics:
recover()only stops a panic when called directly by the deferred function itself.containsRecoverCallwalks the entire subtree of the defer body without stopping at nested*ast.FuncLitboundaries, so a pattern like:is incorrectly accepted as safe (no diagnostic), even though the panic still crashes the process. A linter whose whole purpose is flagging panic-unsafe goroutines producing a silent false negative here is worse than no linter at all.
Fix: stop descending into nested
*ast.FuncLitnodes, mirroring the top-level-only restriction already applied inhasTopLevelRecoverDefer, and add a testdata case fordefer func(){ func(){ recover() }() }()to lock in the fix.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[/tdd] Missing test fixture for a goroutine that contains a nested function literal with its own
defer/recover— the linter should still flag the outer goroutine because the nested recover only protects the inner call.💡 Suggested fixture to add
This also validates that
hasTopLevelRecoverDefercorrectly restricts itself to the top level ofbody.Listand does not descend into nested function bodies.@copilot please address this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing test case for the highest-risk failure mode: a
recover()reachable only via a nested closure inside the defer literal.💡 Details
All four fixture cases test direct top-level patterns (direct recover, no recover, named-function goroutine, unrelated defer). None exercise
containsRecoverCall's unrestricted recursive descent, which is exactly where the false-negative bug lives (see companion comment ongoroutinemissingrecover.go). Add:Without this, the fix for the false negative has no regression guard.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.