-
Notifications
You must be signed in to change notification settings - Fork 170
Standardize API error handling #3218
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
Conversation
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.
Large PR Detected
This PR exceeds 1000 lines of changes and requires justification before it can be reviewed.
How to unblock this PR:
Add a section to your PR description with the following format:
## Large PR Justification
[Explain why this PR must be large, such as:]
- Generated code that cannot be split
- Large refactoring that must be atomic
- Multiple related changes that would break if separated
- Migration or data transformationAlternative:
Consider splitting this PR into smaller, focused changes (< 1000 lines each) for easier review and reduced risk.
See our Contributing Guidelines for more details.
This review will be automatically dismissed once you add the justification section.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #3218 +/- ##
==========================================
+ Coverage 63.65% 63.93% +0.28%
==========================================
Files 361 363 +2
Lines 35449 35367 -82
==========================================
+ Hits 22566 22613 +47
+ Misses 11072 10946 -126
+ Partials 1811 1808 -3 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
Large PR justification has been provided. Thank you!
|
✅ Large PR justification has been provided. The size review has been dismissed and this PR can now proceed with normal review. |
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.
Pull request overview
This PR implements centralized error handling for the API layer, replacing scattered http.Error() calls with a standardized approach using HTTP status code annotations on errors.
- Introduces
pkg/errorspackage withWithCode(),Code(), andNew()functions to attach HTTP status codes to errors - Adds
pkg/api/errors.ErrorHandlerdecorator that converts errors to HTTP responses, hiding 5xx error details while exposing 4xx messages - Refactors 13 sentinel errors across the codebase to include HTTP status codes (404, 400, 409, 503, etc.)
- Updates all API handlers in
v1package to return errors instead of writing HTTP responses directly
Reviewed changes
Copilot reviewed 19 out of 19 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| pkg/errors/errors.go | New error package providing CodedError type and utilities for attaching/extracting HTTP status codes |
| pkg/errors/errors_test.go | Comprehensive unit tests for error wrapping, unwrapping, and code extraction |
| pkg/api/errors/handler.go | ErrorHandler decorator that converts returned errors to HTTP responses based on status codes |
| pkg/api/errors/handler_test.go | Unit tests verifying correct HTTP status codes and response bodies for various error scenarios |
| pkg/workloads/types/validate.go | Updates ErrInvalidWorkloadName to include 400 status code |
| pkg/workloads/types/errors/errors.go | Updates ErrRunConfigNotFound to include 404 status code |
| pkg/transport/session/errors.go | Updates 5 session-related errors to include appropriate status codes (404, 409, 400, 503) |
| pkg/secrets/factory.go | Updates 3 secrets errors to include status codes (400, 404) |
| pkg/runner/retriever/retriever.go | Updates 3 retriever errors to include status codes (400, 404) |
| pkg/groups/errors.go | Updates 3 group errors to include status codes (409, 404, 400) |
| pkg/container/runtime/types.go | Updates ErrWorkloadNotFound to include 404 status code |
| pkg/api/v1/workloads.go | Refactors 14 handler methods to return errors, removes manual http.Error calls, applies ErrorHandler decorator |
| pkg/api/v1/workloads_test.go | Updates test assertions for lowercase error messages and wraps handlers with ErrorHandler |
| pkg/api/v1/secrets.go | Refactors 5 handler methods to return errors, removes manual http.Error calls, applies ErrorHandler decorator |
| pkg/api/v1/secrets_test.go | Updates test assertions for lowercase error messages and wraps handlers with ErrorHandler |
| pkg/api/v1/groups.go | Refactors 4 handler methods to return errors, removes manual http.Error calls, applies ErrorHandler decorator |
| pkg/api/v1/groups_test.go | Updates test assertions for lowercase error messages and wraps handlers with ErrorHandler |
| pkg/api/v1/clients.go | Refactors 6 handler methods to return errors, renames internal helper method, applies ErrorHandler decorator |
| docs/error-handling.md | Documents new error handling pattern with examples of WithCode, Code, and ErrorHandler usage |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
eleftherias
left a comment
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.
This is a great change!
I noted a couple more places where the code needs to be updated.
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
Signed-off-by: Jeremy Drouillard <jeremy@stacklok.com>
39bae64 to
bf63c03
Compare
eleftherias
left a comment
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.
There is a CodeQL warning, but I believe it's unrelated to you changes and already documented with the comment // #nosec G304 - filePath is controlled by getFilePath which ensures it's within our designated directory
Summary
This PR implements standardized error handling for the
thvAPI as described in #3106. Previously, error-to-HTTP-status-code mapping was duplicated and inconsistent across API handlers. This change introduces a centralized error handling mechanism using anErrorHandlerdecorator.Large PR Justification
Readers will find these changes are pretty simple, so it made sense to do the entire refactor in one PR. Most of the changes come from rewriting existing errors to follow the new pattern.
Changes
New Error Package (
pkg/errors)WithCode(error, int)to wrap errors with HTTP status codesCode(error)to extract HTTP status codes from errors (defaults to 500)New(msg, code)to create new errors with codesHasCode(error)to check if an error has an associated codeerrors.Is()anderrors.As()through properUnwrap()implementationNew API Error Handler (
pkg/api/errors)ErrorHandlerdecorator that wraps handlers returningerrorUpdated Sentinel Errors
Wrapped existing sentinel errors with appropriate HTTP status codes:
groups.ErrGroupAlreadyExists→ 409 Conflictgroups.ErrGroupNotFound→ 404 Not Foundgroups.ErrInvalidGroupName→ 400 Bad Requestruntime.ErrWorkloadNotFound→ 404 Not Foundworkloads/types.ErrInvalidWorkloadName→ 400 Bad Requestworkloads/types/errors.ErrRunConfigNotFound→ 404 Not Foundretriever.ErrBadProtocolScheme→ 400 Bad Requestretriever.ErrImageNotFound→ 404 Not Foundretriever.ErrInvalidRunConfig→ 400 Bad Requestsecrets.ErrUnknownManagerType→ 400 Bad Requestsecrets.ErrSecretsNotSetup→ 404 Not Foundsecrets.ErrKeyringNotAvailable→ 400 Bad Requestsession.ErrSessionNotFound→ 404 Not FoundRefactored API Handlers
Updated all API handlers in
pkg/api/v1to:errorinstead of writinghttp.ErrordirectlyErrorHandlerdecorator in router setuperrors.IschecksAffected files:
pkg/api/v1/workloads.gopkg/api/v1/groups.gopkg/api/v1/clients.gopkg/api/v1/secrets.goDocumentation
docs/error-handling.mdto reflect the new error handling strategyTesting
pkg/errorspackage coveringWithCode,Code,HasCode,New, and error unwrappingErrorHandlerdecorator verifying correct status codes and response body contentCloses #3106