Repository navigation
Rethrow caller failures instead of reporting them as Bitbucket errors - #11
Merged
Merged
Conversation
A failure the HTTP stack hits before any response that is not an I/O failure is the caller's own, e.g. an OkHttp interceptor refusing a request because the caller's throttle budget is used up. The fallbacks turned it into an Error, so the caller's signal was lost: Cortex's IntegrationThrottleException, meant to reschedule the task, became a Bitbucket error. getErrors(Throwable) and RawContentOnError now rethrow it. Bitbucket's answers (any status) and I/O failures without a response (timeouts, refused connections) stay errors. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When Cortex's throttle has used up a tenant's request budget, its OkHttp
ThrottleInterceptorrefuses the request by throwingIntegrationThrottleExceptionbefore anything is sent. Cortex relies on that exception reaching the task consumer, which reschedules the task without consuming a retry (Bitbucket Cloud, GitHub and the other integrations do this).jclouds hands every exception to the API's fallback (
InvokeHttpMethod:catch (Throwable t) { return fallback.createOrPropagate(t) }), and our fallbacks turned it into anErrorwithout a status. The signal was lost: in prod, Logic Monitor's scorecard runs kept their previous scores and Paychex's package scans (~10k lookups a day) silently did nothing instead of being rescheduled.Change
getErrors(Throwable)(used by every*OnErrorfallback) andRawContentOnErrorcallpropagateCallerFailurefirst: when the HTTP stack failed before any response (HttpResponseExceptionwithout a response) and the cause is not anIOException, the cause is rethrown.errors()with the statuserrors(), no statuserrors(), no statusVersion
3.1.5-CORTEX.Tests
BitbucketFallbacksMockTest: a non-I/O failure before any response is rethrown (the same instance) bygetErrorsandRawContentOnError— failed before the change; an I/O failure before any response is still an error without a status../gradlew check(267 mock tests + checkstyle) passes.3.1.5-CORTEXfrommavenLocal: a throttle refusal from an interceptor reachesBitbucketOnPremClientServiceImpl's caller asIntegrationThrottleException(fails on3.1.4-CORTEX); Bitbucket tests pass.🤖 Generated with Claude Code