maragudk / maragudk/gomponents
Use errors.As in http.Adapt to find StatusCode in wrapped errors
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 1.9k
- Forks
- 59
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 17
Description
`http.Adapt` looks for a `StatusCode() int` method with a type switch on the returned error:
```go
switch v := err.(type) {
case errorWithStatusCode:
w.WriteHeader(v.StatusCode())
default:
w.WriteHeader(http.StatusInternalServerError)
}
```
That only matches when the returned error itself has the method. Wrapping an error for context is idiomatic Go, but the wrapper doesn't have `StatusCode()`, so the status in the chain is ignored and the response is a 500:
```go
type notFoundError struct{}
func (notFoundError) Error() string { return "not found" }
func (notFoundError) StatusCode() int { return http.StatusNotFound }
// Responds 404.
return html.NotFoundPage(), notFoundError{}
// Responds 500.
return html.NotFoundPage(), fmt.Errorf("get user %v: %w", id, notFoundError{})
```
Verified on main (833b404) with `httptest`.
Proposal: find the status with `errors.As`, so any error in the chain that has `StatusCode()` sets the response status. Errors that match today still match, because `errors.As` checks the error itself first. The only change is for wrapped errors, which currently get a 500. `errors.As` has been in the standard library since Go 1.13, so the Go 1.18 minimum is unaffected.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start at http.Adapt and inspect its existing error-to-status handling and related tests. Use httptest to compare an unwrapped StatusCode error with the same error wrapped using %w. Done means wrapped errors in the chain produce their StatusCode while existing direct-error behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- api, backend
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 76/100