diff --git a/analysis_options.yaml b/analysis_options.yaml index e5eaf7ca..03a4220e 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -154,18 +154,6 @@ dart_code_metrics: # Dart Specific - binary-expression-operand-order - double-literal-format - - prefer-match-file-name: - exclude: - - packages/*/test/** - - packages/*/example/** - - packages/**/util/** - - packages/**/utils.dart - - packages/stream_chat/lib/src/client/client.dart - - packages/stream_chat/lib/src/core/api/responses.dart - - packages/stream_chat/lib/src/core/api/requests.dart - - packages/stream_chat/lib/src/core/platform_detector/** - - packages/stream_chat_persistence/lib/src/db/shared/** - - packages/stream_chat_localizations/lib/src/stream_chat_localizations.dart - no-boolean-literal-compare - no-equal-then-else - no-empty-block: diff --git a/packages/stream_chat/CHANGELOG.md b/packages/stream_chat/CHANGELOG.md index d27ac852..3f20271f 100644 --- a/packages/stream_chat/CHANGELOG.md +++ b/packages/stream_chat/CHANGELOG.md @@ -3,7 +3,8 @@ 🐞 Fixed - [[#799]](https://github.com/GetStream/stream-chat-flutter/issues/799) Fixed `totalUnreadCount` is not updating when - app is resumed from background mode + app is resumed from background mode. +- Fix retry mechanism failing in some cases. ## 3.3.0 diff --git a/packages/stream_chat/lib/src/client/channel.dart b/packages/stream_chat/lib/src/client/channel.dart index 657b8617..51034d3a 100644 --- a/packages/stream_chat/lib/src/client/channel.dart +++ b/packages/stream_chat/lib/src/client/channel.dart @@ -1698,7 +1698,7 @@ class ChannelClientState { } _channelState = _channelState.copyWith( - messages: newMessages, + messages: newMessages..sort(_sortByCreatedAt), channel: _channelState.channel?.copyWith( lastMessageAt: message.createdAt, ), diff --git a/packages/stream_chat/lib/src/client/retry_queue.dart b/packages/stream_chat/lib/src/client/retry_queue.dart index c441b5fb..e1b6df70 100644 --- a/packages/stream_chat/lib/src/client/retry_queue.dart +++ b/packages/stream_chat/lib/src/client/retry_queue.dart @@ -71,14 +71,15 @@ class RetryQueue { /// Add a list of messages void add(List messages) { if (messages.isEmpty) return; - if (_messageQueue.containsAllMessage(messages)) return; + if (!_messageQueue.containsAllMessage(messages)) { + logger?.info('Adding ${messages.length} messages'); + final messageList = _messageQueue.toList(); + // we should not add message if already available in the queue + _messageQueue.addAll(messages.where( + (it) => !messageList.any((m) => m.id == it.id), + )); + } - logger?.info('Adding ${messages.length} messages'); - final messageList = _messageQueue.toList(); - // we should not add message if already available in the queue - _messageQueue.addAll(messages.where( - (it) => !messageList.any((m) => m.id == it.id), - )); _startRetrying(); } @@ -90,17 +91,21 @@ class RetryQueue { while (_messageQueue.isNotEmpty) { logger?.info('${_messageQueue.length} messages remaining in the queue'); final message = _messageQueue.first; - await _runAndRetry(message); + final succeeded = await _runAndRetry(message); + if (!succeeded) { + _messageQueue.toList().forEach(_sendFailedEvent); + break; + } } _isRetrying = false; } - Future _runAndRetry(Message message) async { + Future _runAndRetry(Message message) async { var attempt = 1; final maxAttempt = _retryPolicy.maxRetryAttempts; // early return in case maxAttempt is less than 0 - if (attempt > maxAttempt) return; + if (attempt > maxAttempt) return false; // ignore: literal_only_boolean_expressions while (true) { @@ -109,8 +114,12 @@ class RetryQueue { await _retryMessage(message); logger?.info('Message (${message.id}) sent successfully'); _messageQueue.removeMessage(message); - break; - } on StreamChatError catch (e) { + return true; + } catch (e) { + if (e is! StreamChatNetworkError || !e.isRetriable) { + _messageQueue.removeMessage(message); + return true; + } // retry logic final maxAttempt = _retryPolicy.maxRetryAttempts; if (attempt < maxAttempt) { @@ -143,16 +152,9 @@ class RetryQueue { _sendFailedEvent(message); break; } - } catch (e) { - logger?.info( - 'API call failed due to unknown error (attempt $attempt). ' - 'Giving up for now, will retry when connection recovers. ' - 'Error was $e', - ); - _sendFailedEvent(message); - break; } } + return false; } void _sendFailedEvent(Message message) { diff --git a/packages/stream_chat_flutter/lib/src/message_widget.dart b/packages/stream_chat_flutter/lib/src/message_widget.dart index 6182df54..4010b11b 100644 --- a/packages/stream_chat_flutter/lib/src/message_widget.dart +++ b/packages/stream_chat_flutter/lib/src/message_widget.dart @@ -832,8 +832,8 @@ class _MessageWidgetState extends State ), if (isFailedState) Positioned( - left: widget.reverse ? 0 : null, - right: widget.reverse ? null : 0, + right: widget.reverse ? 0 : null, + left: widget.reverse ? null : 0, bottom: showBottomRow ? 18 : -2, child: StreamSvgIcon.error(size: 20), ),