Skip to content

refactor(recovery): smart error comparison #4142

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

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

zeek0x
Copy link
Contributor

@zeek0x zeek0x commented Jan 18, 2025

Hi :)

While casually looking through the recover.go code, I noticed some logic that identifies errors by matching strings within the error message. Switching to direct error comparisons can improve the maintainability of the code.

@zeek0x zeek0x force-pushed the refactor/smart-error-comparison branch from d569590 to b9bb8d1 Compare January 19, 2025 03:20
@zeek0x
Copy link
Contributor Author

zeek0x commented Jan 19, 2025

I noticed a missed variable name rename, so I fixed it and force-pushed 🙇

@appleboy appleboy requested a review from Copilot May 21, 2025 00:26
@appleboy
Copy link
Member

Please write unit testing.

@appleboy appleboy added this to the v1.11 milestone May 21, 2025
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the panic recovery logic in recovery.go to use direct errors.Is comparisons for broken pipe and connection reset errors instead of substring matching, improving maintainability.

  • Replace substring-based detection of broken connections with errors.Is against syscall.EPIPE and syscall.ECONNRESET.
  • Rename variables for clarity (errrec, brokenPipeisBrokenPipeOrConnReset).
  • Remove deprecated net.OpError branch and add syscall import.
Comments suppressed due to low confidence (2)

recovery.go:61

  • [nitpick] The variable name isBrokenPipeOrConnReset is quite long; consider shortening it (e.g., brokenConn) for readability.
var isBrokenPipeOrConnReset bool

recovery.go:64

  • The errors package is used here but not imported; add import "errors" to the import block to avoid a compile error.
isBrokenPipeOrConnReset = errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)

@zeek0x
Copy link
Contributor Author

zeek0x commented May 28, 2025

@appleboy

Please write unit testing.

There was already a good unit test for this fix, so I changed it to fit better.

@appleboy appleboy requested a review from Copilot May 31, 2025 00:42
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR refactors the recovery logic by switching from string matching to direct error comparisons, improving maintainability and clarity.

  • Updated tests to verify error conditions using syscall.Errno comparisons.
  • Revised the panic recovery handler to compare errors with errors.Is and log accordingly.

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
recovery_test.go Updated test assertions to directly compare syscall.Errno error values.
recovery.go Refactored panic recovery logic to compare errors using errors.Is with syscall errors.

Comment on lines +62 to +64
err, ok := rec.(error)
if ok {
isBrokenPipeOrConnReset = errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
Copy link
Preview

Copilot AI May 31, 2025

Choose a reason for hiding this comment

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

Consider explicitly handling cases where recover() returns a non-error value to clarify the expected type and avoid potential issues when rec is not an error.

Suggested change
err, ok := rec.(error)
if ok {
isBrokenPipeOrConnReset = errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
var err error
switch v := rec.(type) {
case error:
err = v
isBrokenPipeOrConnReset = errors.Is(err, syscall.EPIPE) || errors.Is(err, syscall.ECONNRESET)
default:
err = fmt.Errorf("panic of unknown type: %v", v)

Copilot uses AI. Check for mistakes.

Copy link

codecov bot commented May 31, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.92%. Comparing base (3dc1cd6) to head (4732fa7).
Report is 129 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #4142      +/-   ##
==========================================
- Coverage   99.21%   98.92%   -0.30%     
==========================================
  Files          42       44       +2     
  Lines        3182     3432     +250     
==========================================
+ Hits         3157     3395     +238     
- Misses         17       26       +9     
- Partials        8       11       +3     
Flag Coverage Δ
?
--ldflags="-checklinkname=0" -tags sonic 98.85% <100.00%> (?)
-tags go_json 98.85% <100.00%> (?)
-tags nomsgpack 98.90% <100.00%> (?)
go-1.18 ?
go-1.19 ?
go-1.20 ?
go-1.21 ?
go-1.23 98.92% <100.00%> (?)
go-1.24 98.92% <100.00%> (?)
macos-latest 98.92% <100.00%> (-0.30%) ⬇️
ubuntu-latest 98.92% <100.00%> (-0.30%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@zeek0x
Copy link
Contributor Author

zeek0x commented Jun 1, 2025

It looks like coverage dropped because the file got shorter, not because there's more untested code.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants