distinguish user errors from internal errors#7980
distinguish user errors from internal errors#7980aaryan359 wants to merge 7 commits intojaegertracing:mainfrom
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7980 +/- ##
==========================================
+ Coverage 95.47% 95.48% +0.01%
==========================================
Files 316 316
Lines 16756 16756
==========================================
+ Hits 15997 15999 +2
+ Misses 593 592 -1
+ Partials 166 165 -1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
@jkowall and @yurishkuro, can you review this please? Does this look good? |
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
0fa7435 to
2c29ceb
Compare
|
Seems like some issue with the tests, please verify and fix. Copilot is reviewing it now too. Thanks. |
There was a problem hiding this comment.
Pull request overview
Updates the HotROD example’s error handling so that user-caused failures (e.g., invalid customer IDs) are surfaced as client errors (400-level) instead of being treated as internal server failures (500).
Changes:
- Introduces typed HTTP-related errors (
BadRequestError,HTTPError) and an auto-mapping helper (HandleErrorAuto) inhttperr. - Updates frontend and customer services to use
HandleErrorAutowhen handling downstream/service errors. - Adds unit tests covering the new error types/handler behavior and the customer database invalid-customer path.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| examples/hotrod/services/frontend/server.go | Uses auto HTTP status mapping when bestETA.Get() fails to avoid always returning 500. |
| examples/hotrod/services/customer/server.go | Uses auto HTTP status mapping for database lookup errors. |
| examples/hotrod/services/customer/database.go | Returns a typed bad-request error for invalid customer IDs. |
| examples/hotrod/pkg/tracing/http.go | Propagates downstream HTTP status codes via a typed HTTPError. |
| examples/hotrod/pkg/httperr/httperr.go | Adds typed errors and HandleErrorAuto to map errors to appropriate status codes. |
| examples/hotrod/pkg/httperr/httperr_test.go | Adds tests for HandleError, HandleErrorAuto, and the new error constructors. |
| examples/hotrod/services/customer/database_test.go | Adds tests validating success cases and the invalid-customer error type. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| @@ -17,3 +49,27 @@ func HandleError(w http.ResponseWriter, err error, statusCode int) bool { | |||
| http.Error(w, string(err.Error()), statusCode) | |||
There was a problem hiding this comment.
Redundant conversion: err.Error() already returns a string, so wrapping it in string(...) is unnecessary and may be flagged by linters (e.g., staticcheck S1025).
| http.Error(w, string(err.Error()), statusCode) | |
| http.Error(w, err.Error(), statusCode) |
| "net/http" | ||
| ) | ||
|
|
||
| // BadRequestError represents a user error (4xx status code) |
There was a problem hiding this comment.
The comment says BadRequestError represents a user error "(4xx status code)", but the implementation only maps this type to HTTP 400. Consider updating the comment to avoid implying it can represent other 4xx codes.
| // BadRequestError represents a user error (4xx status code) | |
| // BadRequestError represents a user error mapped to HTTP 400 (Bad Request) |
Signed-off-by: aaryan359 <aaryanmeena96@gmail.com>
|
@jkowall, I fixed the test and also improved the code review. Now is it looking good. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if httperr.HandleErrorAuto(w, err) { | ||
| s.logger.For(ctx).Error("request failed", zap.Error(err)) | ||
| return |
There was a problem hiding this comment.
HandleErrorAuto may be returning a 4xx (e.g., invalid customer ID), but this branch always logs at Error level. That can create noisy logs/alerts for user-caused failures. Consider downgrading the log level for client errors (e.g., BadRequestError or HTTPError with StatusCode < 500) and reserving Error logs for 5xx/unexpected errors.
| if httperr.HandleErrorAuto(w, err) { | ||
| s.logger.For(ctx).Error("request failed", zap.Error(err)) | ||
| return |
There was a problem hiding this comment.
Same as frontend: this logs at Error level even when HandleErrorAuto maps the error to a 4xx user error. Consider logging 4xx as Info/Debug and using Error only for 5xx, based on BadRequestError / HTTPError.StatusCode.
| func TestDatabaseGetValidCustomer(t *testing.T) { | ||
| logger := log.NewFactory(zap.NewNop()) | ||
| db := newDatabase(trace.NewNoopTracerProvider().Tracer("test"), logger) | ||
|
|
||
| // Test getting a valid customer | ||
| customer, err := db.Get(context.Background(), 123) | ||
| require.NoError(t, err) |
There was a problem hiding this comment.
These unit tests call db.Get, which sleeps using config.MySQLGetDelay (default is 300ms) and can make the test suite noticeably slower. Consider overriding config.MySQLGetDelay/MySQLGetDelayStdDev (and optionally MySQLMutexDisabled) to near-zero in the tests (with t.Cleanup to restore) so tests stay fast.
| if res.StatusCode >= http.StatusBadRequest { | ||
| body, err := io.ReadAll(res.Body) | ||
| if err != nil { | ||
| return err | ||
| } | ||
| return errors.New(string(body)) | ||
| return httperr.NewHTTPError(res.StatusCode, string(body)) | ||
| } |
There was a problem hiding this comment.
The response body from http.Error typically already ends with a newline; wrapping it directly into an HTTPError and later re-emitting it via http.Error can lead to double newlines in the propagated message. Consider trimming whitespace (e.g., strings.TrimSpace) when constructing the HTTPError message.
Which problem is this PR solving?
Description of the changes
How was this change tested?
curland verified the service returns a clear error message with the correct HTTP status code.Checklist
jaeger:make lint test