fix: stop reporting expected client errors to Sentry#124
Conversation
5645240 to
aa642f5
Compare
📝 WalkthroughWalkthroughThe PR improves error handling across OAuth and client flows. Request handling now checks for client-side context cancellation before proceeding. OAuth handlers return standard library error types instead of custom formatted errors, Sentry reporting becomes conditional (skipping 4xx errors and context cancellations), and client error matching uses proper type-checking semantics. ChangesError Handling and Cancellation Improvements
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
internal/gateway/server.go (1)
37-52: ⚡ Quick winCheck cancellation before the token lookup.
ctx.Err()is only consulted afterorigin.CheckTokenFunc(...), so a request that is already canceled still does token-store work before this handler exits. Move the guard ahead of Line 47 and passctxthrough so the abort path stays cheap.Suggested change
func (origin *OriginServer) ServeHTTP(w http.ResponseWriter, r *http.Request) { ctx := r.Context() @@ - tokenInfo, err := origin.CheckTokenFunc(r.Context(), token) + if ctx.Err() == context.Canceled { + return + } + + tokenInfo, err := origin.CheckTokenFunc(ctx, token) // Client has aborted the request if ctx.Err() == context.Canceled { return }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@internal/gateway/server.go` around lines 37 - 52, Move the request-cancellation guard to run immediately after obtaining ctx to avoid doing token-store work for already-aborted requests: after "ctx := r.Context()" check "if ctx.Err() == context.Canceled { return }" before calling origin.CheckTokenFunc; also change the CheckTokenFunc call to pass the local ctx variable (origin.CheckTokenFunc(ctx, token)) so the cancelable context is used for token lookup. Ensure the early-return remains in place and the rest of the logic (public access proxy, token extraction) still runs in the correct order.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@internal/tokens/oauth.go`:
- Around line 101-107: The warning currently logs full redirectURI and baseURI
which can leak sensitive path/query/userinfo; update the log in the branch that
checks parsedClientUri.Scheme != parsedRedirect.Scheme ||
!isUriValid(clientHost, redirectHost) so it only records parsed scheme and host
values (e.g., parsedClientUri.Scheme, clientHost, parsedRedirect.Scheme,
redirectHost) using logrus.WithField/WithFields and then return
oauthErrors.ErrInvalidRequest; do not include redirectURI or baseURI in the log.
---
Nitpick comments:
In `@internal/gateway/server.go`:
- Around line 37-52: Move the request-cancellation guard to run immediately
after obtaining ctx to avoid doing token-store work for already-aborted
requests: after "ctx := r.Context()" check "if ctx.Err() == context.Canceled {
return }" before calling origin.CheckTokenFunc; also change the CheckTokenFunc
call to pass the local ctx variable (origin.CheckTokenFunc(ctx, token)) so the
cancelable context is used for token lookup. Ensure the early-return remains in
place and the rest of the logic (public access proxy, token extraction) still
runs in the correct order.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 8b75a284-676f-430a-8425-a890c2597d3b
📒 Files selected for processing (4)
internal/clients/clients.gointernal/gateway/server.gointernal/tokens/oauth.gointernal/tokens/tokens.go
The OAuth handlers reported every authorize/token rejection to Sentry — malformed requests, unknown clients, redirect-URI mismatches, disallowed scopes and aborted connections. These are 4xx-class, caller-driven outcomes, not server faults, and made up the large majority of this project's Sentry volume. Decide per call site whether an error is worth reporting: - Authorize/token handlers report only errors that aren't a known go-oauth2 protocol error with a 4xx status (so 5xx and unrecognised errors, e.g. a DB failure, are still captured). - preRedirectErrorHandler no longer captures; the error is reported once downstream in AuthorizationHandler instead of twice. - checkRedirectUriDomain and AuthorizeScopeHandler return the standard OAuth errors (invalid_request / invalid_scope) and log the detail, instead of bespoke errors that bypass classification. - FetchClientHandler reports only genuine DB failures, not ErrRecordNotFound for unknown client ids. - InternalErrorHandler skips context.Canceled (client aborted).
aa642f5 to
738e2aa
Compare
Per review: the mismatch warning logged the full client-supplied redirect_uri and the registered base URI, which can leak path/query/ userinfo and adds high-cardinality fields on a hot bad-request path. Log only the parsed scheme and host, matching what the previous error message exposed.
Problem
The OAuth handlers reported every authorize/token rejection to Sentry — malformed requests, unknown clients, redirect-URI mismatches, disallowed scopes and aborted connections. These are 4xx-class, caller-driven outcomes, not server faults, and made up the large majority of this project's Sentry volume.
Approach
Rather than one central filter (which risked swallowing real errors —
errors.StatusCodes/Descriptionsincludeserver_error500 andtemporarily_unavailable503), each call site decides explicitly, with local knowledge:if code, ok := oauthErrors.StatusCodes[err]; !ok || code >= 500.AuthorizationHandlerinstead of twice.invalid_request/invalid_scope) and log the detail, instead of bespoke errors that bypass classification.ErrRecordNotFoundfor an unknown client id.context.Canceled(client aborted the request).context.Canceledearly-return.No behavioural change for clients — the same HTTP status/redirect outcomes — only what reaches Sentry changes. Genuine server errors (DB failures, JWT injection failures, admin client CRUD, 5xx OAuth errors) are still reported.
Verification
go build ./...✅go vet ./internal/...✅main(preservesisUriValid,AllowPublicAccess,ContextKey).Summary by CodeRabbit