feat: [CHA-2958] typed error hierarchy + waitForTask#65
Open
mogita wants to merge 5 commits into
Open
Conversation
Add StreamApiException, StreamRateLimitException, StreamTransportException, and StreamTaskException as checked subclasses of the existing StreamException. Carries the previously-dropped APIError fields (unrecoverable, details) and parses the Retry-After header (RFC 7231: integer seconds + HTTP-date) on 429. Transport-layer IO failures are now classified into a per-error-type enum and the cause chain is preserved at every wrap point. Adds client.waitForTask(taskId) as a customer-facing main-source helper that polls until terminal. Failed tasks throw StreamTaskException populated from ErrorResult; the wait elapsing throws StreamTransportException(errorType= timeout). Removes the duplicate test-only waitForTask helper from ChatTestBase and updates the 5 callers. No breaking API changes: subclasses extend the existing checked StreamException, getResponseData() continues to return a populated mirror on API errors, and existing throws StreamException declarations continue to compile.
Auto-formatting via `./gradlew spotlessApply` over the CHA-2958 files. No behavior change.
…heck Two test-only fixes for CI on JDK 21: 1. `request()` helper now declares `throws StreamException` (StreamRequest's constructor is checked since CHA-2958's reshape). 2. `instanceof RuntimeException` against a statically-typed `StreamException` is an unconditional-pattern compile error on JDK 21; use `RuntimeException.class.isInstance(e)` to keep the runtime assertion.
CI sets `STREAM_BASE_URL: ${{ vars.STREAM_BASE_URL }}`, which renders to an
empty string when the GitHub variable is not configured. With the previous
`env.getOrDefault(..., System.getProperty(...))` shape, an empty env value
won and overrode any `io.getstream.url` system property set by tests, so
unit tests fell through to the real Stream API using the real credentials
also injected via env. Tests in `StreamWaitForTaskTest` hit the live
`get-task/t1` endpoint and got `StreamApiException: Can't find task with id`.
Now the env var falls through to the system property when it is null or
blank, so MockWebServer-backed tests work and any future deployment that
leaves STREAM_BASE_URL empty falls back to the SDK default base URL
instead of broken empty URLs.
CI sets STREAM_BASE_URL to the real Stream API URL, and the Properties-based StreamHTTPClient constructor gives env vars priority over system properties. The previous setUp set `io.getstream.url` via System.setProperty and then called `new StreamSDKClient(System.getProperties())`, which still read the real-URL env var and pointed every request at the live API. The mocked task JSONs were never consumed and the SDK got back real "Can't find task with id" responses. Switched setUp to the credentials-only StreamHTTPClient constructor (which does not read env vars) and used reflection to force the private `baseUrl` field onto the MockWebServer URL. The SDK client is then wrapped via `new StreamSDKClient(StreamHTTPClient)`. Removes the system-property dance and the env precedence problem entirely.
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.
Summary
StreamException:StreamApiException— HTTP 4xx/5xx envelope (statusCode, code, exceptionFields, unrecoverable, rawResponseBody, moreInfo, details)StreamRateLimitException— HTTP 429 + parsedRetry-AfterasDurationStreamTransportException— IO failures with classifiederrorTypeenum, cause preservedStreamTaskException— failed async task withErrorResultfieldsAPIErrorparser now surfaces the two previously-dropped fields:unrecoverableanddetails.Retry-Afterparser handles RFC 7231 §7.1.3 integer + IMF-fixdate HTTP-date; graceful on missing / unparseable.client.waitForTask(taskId)customer-facing helper (replaces the test-onlyChatTestBase.waitForTask).No breaking API changes — all new types are subclasses of the existing checked
StreamException.catch (StreamException)still works;throws StreamExceptionstill compiles.Notable
StreamTaskException.getStackTraceText()instead ofgetStackTrace()to avoid clobberingThrowable.getStackTrace().ChatTestBase.waitForTasktoclient.waitForTask. Old test helper silently swallowedstatus="failed"; the new helper throwsStreamTaskException.Test plan
./gradlew build --info./gradlew test --no-daemon./gradlew spotlessCheck