Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/stream_core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
- Replaced `StreamApiError.isTokenExpiredError`, `isClientError` and `isRateLimitError`: the conditions live on `StreamErrorCode` and `StreamApiException` as `isTokenExpired`, `isTokenNotYetValid`, `isTokenSignatureInvalid`, `isApiKeyInvalid` and `isRateLimited`; `StreamApiError` keeps only `isRateLimited`
- `StreamApiError.code` is typed `StreamErrorCode` rather than `int`; construction takes `StreamErrorCode(40)` in place of `40`, reads are unchanged
- `AuthInterceptor` extends `Interceptor` rather than `QueuedInterceptor`, so requests are no longer serialised against one another
- `WebSocketConnectionState.isAutomaticReconnectionEnabled` reads the error's facts: token conditions that heal and transient network failures reconnect; refused signatures or API keys, other 4xx and `unrecoverable` verdicts do not
- `WebSocketConnectionState.isAutomaticReconnectionEnabled` reads the error's facts: token conditions that heal, rate limits, server-side processing timeouts and transient network failures reconnect; refused signatures or API keys, other 4xx and `unrecoverable` verdicts do not
- `Result.getOrElse`, `getOrDefault`, `recover` and `recoverCatching` return the result's own type and no longer take a type parameter. To widen, widen the result (`Result<num> widened = intResult`) or use `fold`
- Replaced the logger: `StreamLogger` is the handle you write with and a `StreamLogHandler` is where records go, so `Priority`, `MessageBuilder`, `Tag`, `IsLoggableValidator` and `Finder` are renamed or gone
- `LoggingInterceptor` writes through the logger rather than printing, so it is silent until an app asks for records. Its `logPrint` is now optional, and it takes a `tag`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,23 @@ class AuthInterceptor extends Interceptor {
// other token codes are clock or configuration problems a refresh cannot
// help.
final error = err.toStreamException();
if (error is! StreamApiException || !error.isTokenExpired) return handler.next(err);
if (error is! StreamApiException || !error.isTokenExpired) {
// The classification is done; handing it on as a StreamDioException is
// what ApiErrorInterceptor would build anyway, and spares it reading the
// same body a second time.
if (err is StreamDioException) return handler.next(err);

return handler.next(
StreamDioException(
exception: error,
requestOptions: err.requestOptions,
response: err.response,
type: err.type,
stackTrace: err.stackTrace,
message: err.message,
),
);
}

final options = err.requestOptions;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -315,12 +315,13 @@ sealed class DisconnectionSource extends Equatable {
StreamApiException(isTokenExpired: true) => true,
StreamApiException(isTokenNotYetValid: true) => true,
StreamApiException(isRateLimited: true) => true,
StreamApiException(statusCode: 408) => true,
StreamApiException(:final statusCode) => statusCode < 400 || statusCode >= 500,
StreamNetworkException(closeCode: CloseCode.normalClosure) => false,
StreamNetworkException() => true,
StreamAuthenticationException() => false,
StreamClientException() => true,
_ => true,
null => true,
},
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,15 @@ void main() {
expect(state.isAutomaticReconnectionEnabled, isTrue);
});

test('automatic reconnection is enabled when the server timed out processing', () {
// 48 is a request timeout, sent as 408: about the moment, not a verdict on
// the request, so it is retried with backoff like the other 5xx-shaped
// failures rather than refused like the rest of the 4xx range.
final state = _serverDisconnect(_apiError(48, statusCode: 408));

expect(state.isAutomaticReconnectionEnabled, isTrue);
});

test('automatic reconnection is disabled for any other client error', () {
// 17 is not allowed, and retrying does not change the answer.
final state = _serverDisconnect(_apiError(17, statusCode: 403));
Expand Down
Loading