Skip to content
This repository was archived by the owner on Nov 10, 2025. It is now read-only.
This repository was archived by the owner on Nov 10, 2025. It is now read-only.

False positive when comparing any #93

@mattdowdell

Description

@mattdowdell

I came across the following code in connectrpc.com/connect:

r := recover()
// net/http checks for ErrAbortHandler with ==, so we should too.
if r == http.ErrAbortHandler { //nolint:errorlint,goerr113
	panic(r) //nolint:forbidigo
}
retErr = i.handle(ctx, req.Spec(), req.Header(), r)

We can see a similar comparison in the stdlib:

if err := recover(); err != nil && err != ErrAbortHandler {
	const size = 64 << 10
	buf := make([]byte, size)
	buf = buf[:runtime.Stack(buf, false)]
	c.server.logf("http: panic serving %v: %v\n%s", c.remoteAddr, err, buf)
}

This code is fairly common across HTTP middleware that seeks to replace panics with an internal error response and add some additional observability (logs, etc.) while we're there.

The use of != is likely because recover returns any rather than an error implementation. As such, it would require an additional cast to be able to use errors.Is. Regardless, it seems the de facto correct way to test for http.ErrAbortHandler is with == or != and the lint suppression represents a false positive.

I see two ways out of this, although perhaps there's a third option I haven't spotted:

  1. Skip checks if either operand is any, or perhaps does not implement error, solving the general case.
  2. Add recover with http.ErrAbortHandler to the existing allowlist, solving the specific case.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions