Exception Handling

The SDK groups errors into a small typed hierarchy so you can write narrow catch blocks and access structured fields directly, without parsing response bodies yourself.

Exception classes

ClassRaised when
StreamExceptionBase. Every SDK-emitted exception inherits from it.
StreamApiExceptionThe server returned a 4xx or 5xx with the canonical error envelope, or returned a non-success body that could not be parsed.
StreamRateLimitExceptionThe server returned HTTP 429. Subclass of StreamApiException. Adds retryAfter.
StreamTransportExceptionA network-layer failure (connection reset, timeout, DNS, TLS) prevented the request from reaching the server.
StreamTaskExceptionAn async task observed via the task-waiting helper ended with status: "failed".

StreamRateLimitException extends StreamApiException, so a catch (StreamApiException ...) block matches 429s too. Catch the rate-limit subclass first if you want different handling.

Class names per SDK

The hierarchy is the same across SDKs. Class names follow each language's idiom.

ConceptGo (sentinel error)Python / Java / PHPRuby.NET
BaseStreamErrorStreamExceptionGetStreamRuby::StreamErrorGetStreamException
HTTP API errorErrApiResponseStreamApiExceptionGetStreamRuby::ApiErrorGetStreamApiException
HTTP 429ErrRateLimitedStreamRateLimitExceptionGetStreamRuby::RateLimitErrorGetStreamRateLimitException
Transport failureErrTransportStreamTransportExceptionGetStreamRuby::TransportErrorGetStreamTransportException
Task failureErrTaskFailedStreamTaskExceptionGetStreamRuby::TaskErrorGetStreamTaskException

In Go, branch on the sentinel with errors.Is(err, getstream.ErrApiResponse) and extract fields by unwrapping to *StreamError via errors.As.

Fields on the API exception

When the server returns a 4xx or 5xx with the standard error envelope, the API exception carries every documented field. Use these directly instead of re-parsing the response body.

FieldDescription
statusCodeHTTP status code (e.g. 400, 404, 500).
codeStream's numeric error code from the envelope. See the API Error Codes reference.
messageHuman-readable error message.
exceptionFieldsMap of field name to validation message. Populated for 4xx validation errors. Empty otherwise.
unrecoverableWhether the server marked this error as unrecoverable. Honor this when composing retry logic.
rawResponseBodyThe exact bytes of the response body, as a string. Useful for logging and diagnostics.
moreInfoOptional URL pointing to more documentation about the error.
detailsOptional structured payload with error-specific context.

Catching API errors

using GetStream;

try
{
    await client.SendMessageAsync(...);
}
catch (GetStreamRateLimitException ex)
{
    // 429; ex.RetryAfter is a TimeSpan?
    await Task.Delay(ex.RetryAfter ?? TimeSpan.FromSeconds(1));
}
catch (GetStreamApiException ex) when (ex.StatusCode == 422)
{
    foreach (var (field, msg) in ex.ExceptionFields)
    {
        Console.WriteLine($"{field}: {msg}");
    }
    if (ex.Unrecoverable)
    {
        throw;
    }
}

Cause-chain preservation

Every wrapping point preserves the underlying cause via the language-native mechanism. You can always recover the original exception when you need it for diagnostics or instrumentation.

LanguageAccessor
Pythonexc.__cause__
Goerrors.Unwrap(err)
Javaexc.getCause()
PHP$e->getPrevious()
Rubyexc.cause
.NETex.InnerException

Migration notes

Python: deprecated StreamAPIException alias

getstream.base.StreamAPIException (capital API) is preserved as a deprecated alias for StreamApiException. Existing except StreamAPIException blocks and isinstance(exc, StreamAPIException) checks keep working, with a one-time DeprecationWarning on import. Switch to the new spelling at your convenience. The alias is slated for removal in the following minor release.

Ruby: deprecated Stream::APIError alias

GetStreamRuby::APIError (capital API) is preserved as a deprecated alias for GetStreamRuby::ApiError. First access emits a one-time Kernel.warn. Slated for removal in v9.0.

PHP: getCode() semantics

StreamApiException::getCode() continues to return the HTTP status code, the pre-existing behavior inherited from \Exception::getCode(). Stream's canonical numeric error code from the response envelope is now exposed via the new getApiErrorCode(): int. Existing callers branching on $e->getCode() === 429 continue to work. Switch to getApiErrorCode() if you need the envelope code instead of the HTTP status.

.NET: per-status subclasses removed

The previously-published GetStreamAuthenticationException, GetStreamValidationException, and GetStreamFeedException are removed. They were never thrown by the SDK, so no existing catch block was reached. If you have defensive catch blocks for those types, replace them with status-code filters on GetStreamApiException.

// before (never matched)
catch (GetStreamAuthenticationException ex) { ... }

// after
catch (GetStreamApiException ex) when (ex.StatusCode is 401 or 403) { ... }