diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f850806831..57bb28408ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ ### ⬆️ Improved ### ✅ Added +- Added `ChatClientDebugger.onNonFatalErrorOccurred` to handle non-fatal errors. [#4959](https://github.com/GetStream/stream-chat-android/pull/4959) ### ⚠️ Changed diff --git a/docusaurus/android_versioned_docs/version-5.x.x/01-basics/07-debugging.mdx b/docusaurus/android_versioned_docs/version-5.x.x/01-basics/07-debugging.mdx new file mode 100644 index 00000000000..7f04187d2e7 --- /dev/null +++ b/docusaurus/android_versioned_docs/version-5.x.x/01-basics/07-debugging.mdx @@ -0,0 +1,213 @@ +import Tabs from '@theme/Tabs'; +import TabItem from '@theme/TabItem'; + +# Debugging + +:::note +*ChatClientDebugger* might be useful in investigation of issues happening on users side. +::: + +To debug various flows inside the SDK, you can pass your own `ChatClientDebugger` implementation: + + + + +```kotlin +val client = ChatClient.Builder("apiKey", context) + .clientDebugger(CustomChatClientDebugger()) + .build() +``` + + + + +```java +ChatClient client = new ChatClient.Builder("apiKey", context) + .clientDebugger(new CustomChatClientDebugger()) + .build() +``` + + + +### Debug Message Sending + +To debug a message sending flow you can override `ChatClientDebugger.debugSendMessage` function and provide your own `SendMessageDebugger` implementation: + + + + +```kotlin +class CustomChatClientDebugger : ChatClientDebugger { + + override fun onNonFatalErrorOccurred( + tag: String, + src: String, + desc: String, + error: ChatError + ) { + // TODO: Implement your custom logic here + } + + override fun debugSendMessage( + channelType: String, + channelId: String, + message: Message, + isRetrying: Boolean, + ): SendMessageDebugger { + return CustomSendMessageDebugger( + channelType, + channelId, + message, + isRetrying + ) + } +} +``` + + + + +```java +class CustomChatClientDebugger implements ChatClientDebugger { + + @Override + public void onNonFatalErrorOccurred( + @NonNull String tag, + @NonNull String src, + @NonNull String desc, + @NonNull ChatError error + ) { + // TODO: Implement your custom logic here + } + + @Override + public SendMessageDebugger debugSendMessage( + @NonNull String channelType, + @NonNull String channelId, + @NonNull Message message, + boolean isRetrying + ) { + return new CustomSendMessageDebugger( + channelType, + channelId, + message, + isRetrying + ); + } +} +``` + + + +Then in you custom `SendMessageDebugger` implementation you will be able to handle the entire message sending flow: + + + +```kotlin +class CustomSendMessageDebugger( + private val channelType: String, + private val channelId: String, + private val message: Message, + private val isRetrying: Boolean, +) : SendMessageDebugger { + + override fun onStart(message: Message) { + // Called when the message sending flow starts. + } + + override fun onInterceptionStart(message: Message) { + // Called when the message interception before sending it to the API starts. + // Reasons for interception might be: + // - message attachment uploading + // - message enriching by all required information + } + + override fun onInterceptionUpdate(message: Message) { + // Called when there are intermediate message data updates. + } + + override fun onInterceptionStop(result: Result) { + // Called when the message interception before sending it to the API stops. + } + + override fun onSendStart(message: Message) { + // Called when the message sending to the API starts. + } + + override fun onSendStop(result: Result) { + // Called when the message sending to the API stops. + } + + override fun onStop(result: Result) { + // Called when the message sending flow stops. + } +} +``` + + + + +```java +public class CustomSendMessageDebugger implements SendMessageDebugger { + @NonNull + private final String channelType; + @NonNull + private final String channelId; + @NonNull + private final Message message; + @NonNull + private final boolean isRetrying; + + public JavaSendMessageDebugger( + @NonNull String channelType, + @NonNull String channelId, + @NonNull Message message, + boolean isRetrying + ) { + this.channelType = channelType; + this.channelId = channelId; + this.message = message; + this.isRetrying = isRetrying; + } + + @Override + public void onStart(@NonNull Message message) { + // Called when the message sending flow starts. + } + + @Override + public void onInterceptionStart(@NonNull Message message) { + // Called when the message interception before sending it to the API starts. + // Reasons for interception might be: + // - message attachment uploading + // - message enriching by all required information + } + + @Override + public void onInterceptionUpdate(@NonNull Message message) { + // Called when there are intermediate message data updates. + } + + @Override + public void onInterceptionStop(@NonNull Result result) { + // Called when the message interception before sending it to the API stops. + } + + @Override + public void onSendStart(@NonNull Message message) { + // Called when the message sending to the API starts. + } + + @Override + public void onSendStop(@NonNull Result result) { + // Called when the message sending to the API stops. + } + + @Override + public void onStop(@NonNull Result result) { + // Called when the message sending flow stops. + } +} +``` + + \ No newline at end of file diff --git a/docusaurus/docs/Android/01-basics/07-debugging.mdx b/docusaurus/docs/Android/01-basics/07-debugging.mdx index def3fa4824d..9baed860c12 100644 --- a/docusaurus/docs/Android/01-basics/07-debugging.mdx +++ b/docusaurus/docs/Android/01-basics/07-debugging.mdx @@ -37,8 +37,19 @@ To debug a message sending flow you can override `ChatClientDebugger.debugSendMe ```kotlin +import io.getstream.result.Error + class CustomChatClientDebugger : ChatClientDebugger { + override fun onNonFatalErrorOccurred( + tag: String, + src: String, + desc: String, + error: Error, + ) { + // TODO: Implement your custom logic here + } + override fun debugSendMessage( channelType: String, channelId: String, @@ -59,21 +70,33 @@ class CustomChatClientDebugger : ChatClientDebugger { ```java -class CustomChatClientDebugger : ChatClientDebugger { +import io.getstream.result.Error; + +class CustomChatClientDebugger implements ChatClientDebugger { @Override - public void debugSendMessage( + public void onNonFatalErrorOccurred( + @NonNull String tag, + @NonNull String src, + @NonNull String desc, + @NonNull Error error + ) { + // TODO: Implement your custom logic here + } + + @Override + public SendMessageDebugger debugSendMessage( @NonNull String channelType, @NonNull String channelId, @NonNull Message message, - boolean isRetrying, - ): SendMessageDebugger { + boolean isRetrying + ) { return new CustomSendMessageDebugger( channelType, channelId, message, isRetrying - ) + ); } } ``` diff --git a/stream-chat-android-client/api/stream-chat-android-client.api b/stream-chat-android-client/api/stream-chat-android-client.api index fbc6bb9b883..2c741abd04d 100644 --- a/stream-chat-android-client/api/stream-chat-android-client.api +++ b/stream-chat-android-client/api/stream-chat-android-client.api @@ -740,11 +740,13 @@ public final class io/getstream/chat/android/client/clientstate/DisconnectCause$ public abstract interface class io/getstream/chat/android/client/debugger/ChatClientDebugger { public abstract fun debugSendMessage (Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Message;Z)Lio/getstream/chat/android/client/debugger/SendMessageDebugger; + public abstract fun onNonFatalErrorOccurred (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/getstream/result/Error;)V } public final class io/getstream/chat/android/client/debugger/ChatClientDebugger$DefaultImpls { public static fun debugSendMessage (Lio/getstream/chat/android/client/debugger/ChatClientDebugger;Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Message;Z)Lio/getstream/chat/android/client/debugger/SendMessageDebugger; public static synthetic fun debugSendMessage$default (Lio/getstream/chat/android/client/debugger/ChatClientDebugger;Ljava/lang/String;Ljava/lang/String;Lio/getstream/chat/android/models/Message;ZILjava/lang/Object;)Lio/getstream/chat/android/client/debugger/SendMessageDebugger; + public static fun onNonFatalErrorOccurred (Lio/getstream/chat/android/client/debugger/ChatClientDebugger;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lio/getstream/result/Error;)V } public abstract interface class io/getstream/chat/android/client/debugger/SendMessageDebugger { diff --git a/stream-chat-android-client/detekt-baseline.xml b/stream-chat-android-client/detekt-baseline.xml index a8cd9d91dd7..fff3b0090ec 100644 --- a/stream-chat-android-client/detekt-baseline.xml +++ b/stream-chat-android-client/detekt-baseline.xml @@ -6,8 +6,9 @@ FunctionOnlyReturningConstant:StringExtensionsKtTest.kt$StringExtensionsKtTest.Companion$fun createStreamCdnImageLinkWithoutDimensionParameters() LongMethod:ChatClient.kt$ChatClient$private suspend fun handleEvent(event: ChatEvent) LongMethod:ChatClientDebuggerTest.kt$ChatClientDebuggerTest$@BeforeEach fun setUp() + LongMethod:ChatSocket.kt$ChatSocket$@Suppress("ComplexMethod") private fun observeSocketStateService(): Job LongMethod:PinnedMessagesRequest.kt$PinnedMessagesRequest.Companion$fun create( limit: Int, sort: QuerySorter<Message>, pagination: PinnedMessagesPagination, ): PinnedMessagesRequest - LongParameterList:BaseChatModule.kt$BaseChatModule$( private val appContext: Context, private val clientScope: ClientScope, private val userScope: UserScope, private val config: ChatClientConfig, private val notificationsHandler: NotificationHandler, private val notificationConfig: NotificationConfig, private val fileUploader: FileUploader? = null, private val tokenManager: TokenManager = TokenManagerImpl(), private val customOkHttpClient: OkHttpClient? = null, private val lifecycle: Lifecycle, private val httpClientConfig: (OkHttpClient.Builder) -> OkHttpClient.Builder = { it }, ) + LongParameterList:BaseChatModule.kt$BaseChatModule$( private val appContext: Context, private val clientScope: ClientScope, private val userScope: UserScope, private val config: ChatClientConfig, private val notificationsHandler: NotificationHandler, private val notificationConfig: NotificationConfig, private val fileUploader: FileUploader? = null, private val tokenManager: TokenManager = TokenManagerImpl(), private val customOkHttpClient: OkHttpClient? = null, private val clientDebugger: ChatClientDebugger? = null, private val lifecycle: Lifecycle, private val httpClientConfig: (OkHttpClient.Builder) -> OkHttpClient.Builder = { it }, ) MagicNumber:WaveformExtractor.kt$WaveformExtractor$127f MagicNumber:WaveformExtractor.kt$WaveformExtractor$16 MagicNumber:WaveformExtractor.kt$WaveformExtractor$1_000_000f diff --git a/stream-chat-android-client/src/debug/java/io/getstream/chat/android/client/di/ChatModule.kt b/stream-chat-android-client/src/debug/java/io/getstream/chat/android/client/di/ChatModule.kt index bc6a079559b..14c111bd16e 100644 --- a/stream-chat-android-client/src/debug/java/io/getstream/chat/android/client/di/ChatModule.kt +++ b/stream-chat-android-client/src/debug/java/io/getstream/chat/android/client/di/ChatModule.kt @@ -19,6 +19,7 @@ package io.getstream.chat.android.client.di import android.content.Context import androidx.lifecycle.Lifecycle import io.getstream.chat.android.client.api.ChatClientConfig +import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.notifications.handler.NotificationConfig import io.getstream.chat.android.client.notifications.handler.NotificationHandler import io.getstream.chat.android.client.parser.ChatParser @@ -44,6 +45,7 @@ internal class ChatModule( uploader: FileUploader?, tokenManager: TokenManager, customOkHttpClient: OkHttpClient?, + clientDebugger: ChatClientDebugger?, lifecycle: Lifecycle, ) : BaseChatModule( appContext, @@ -55,6 +57,7 @@ internal class ChatModule( uploader, tokenManager, customOkHttpClient, + clientDebugger, lifecycle, ) { diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt index f6e0f98f526..a1a376b5db7 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/ChatClient.kt @@ -3129,6 +3129,7 @@ internal constructor( fileUploader, tokenManager, customOkHttpClient, + clientDebugger, lifecycle, ) diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/debugger/ChatClientDebugger.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/debugger/ChatClientDebugger.kt index 1ee964058e7..8d1f5153749 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/debugger/ChatClientDebugger.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/debugger/ChatClientDebugger.kt @@ -17,12 +17,23 @@ package io.getstream.chat.android.client.debugger import io.getstream.chat.android.models.Message +import io.getstream.result.Error /** * Debugs the [io.getstream.chat.android.client.ChatClient]. */ public interface ChatClientDebugger { + /** + * Called when a non-fatal error occurs. + * + * @param tag The location where the error occurred. + * @param src The source of the error. + * @param desc The description of the error. + * @param error The error that occurred. + */ + public fun onNonFatalErrorOccurred(tag: String, src: String, desc: String, error: Error) {} + /** * Creates an instance of [SendMessageDebugger] that allows you to debug the sending process of a message. * diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/BaseChatModule.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/BaseChatModule.kt index fdc473c38b3..6f47a1c136f 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/BaseChatModule.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/di/BaseChatModule.kt @@ -49,6 +49,7 @@ import io.getstream.chat.android.client.api2.endpoint.ModerationApi import io.getstream.chat.android.client.api2.endpoint.UserApi import io.getstream.chat.android.client.api2.endpoint.VideoCallApi import io.getstream.chat.android.client.clientstate.UserStateService +import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.logger.ChatLogLevel import io.getstream.chat.android.client.network.NetworkStateProvider import io.getstream.chat.android.client.notifications.ChatNotifications @@ -85,6 +86,7 @@ internal open class BaseChatModule( private val fileUploader: FileUploader? = null, private val tokenManager: TokenManager = TokenManagerImpl(), private val customOkHttpClient: OkHttpClient? = null, + private val clientDebugger: ChatClientDebugger? = null, private val lifecycle: Lifecycle, private val httpClientConfig: (OkHttpClient.Builder) -> OkHttpClient.Builder = { it }, ) { @@ -221,6 +223,7 @@ internal open class BaseChatModule( userScope, lifecycleObserver, networkStateProvider, + clientDebugger, ) @Suppress("RemoveExplicitTypeArguments") diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocket.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocket.kt index 3c25a73263e..45f4961987b 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocket.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocket.kt @@ -19,6 +19,7 @@ package io.getstream.chat.android.client.socket import io.getstream.chat.android.client.LifecycleHandler import io.getstream.chat.android.client.StreamLifecycleObserver import io.getstream.chat.android.client.clientstate.DisconnectCause +import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.errors.ChatErrorCode import io.getstream.chat.android.client.events.ChatEvent import io.getstream.chat.android.client.events.ConnectedEvent @@ -48,9 +49,10 @@ internal open class ChatSocket( private val userScope: UserScope, private val lifecycleObserver: StreamLifecycleObserver, private val networkStateProvider: NetworkStateProvider, + private val clientDebugger: ChatClientDebugger? = null, ) { private var streamWebSocket: StreamWebSocket? = null - private val logger by taggedLogger("Chat:Socket") + private val logger by taggedLogger(TAG) private var connectionConf: SocketFactory.ConnectionConf? = null private val listeners = mutableSetOf() private val chatSocketStateService = ChatSocketStateService() @@ -101,7 +103,15 @@ internal open class ChatSocket( logger.i { "[onSocketStateChanged] state: $state" } when (state) { is State.RestartConnection -> { - connectionConf?.let { chatSocketStateService.onReconnect(it, false) } + connectionConf?.let { chatSocketStateService.onReconnect(it, false) } ?: run { + logger.e { "[onSocketStateChanged] #reconnect; connectionConf is null" } + clientDebugger?.onNonFatalErrorOccurred( + tag = TAG, + src = "onSocketStateChanged", + desc = "Failed to reconnect socket on ${state.reason}", + error = Error.GenericError("connectionConf is null"), + ) + } } is State.Connected -> { healthMonitor.ack() @@ -306,6 +316,7 @@ internal open class ChatSocket( } companion object { + private const val TAG = "Chat:Socket" private const val DEFAULT_CONNECTION_TIMEOUT = 60_000L } } diff --git a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocketStateService.kt b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocketStateService.kt index bab80d8ecb2..b0a51d975d4 100644 --- a/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocketStateService.kt +++ b/stream-chat-android-client/src/main/java/io/getstream/chat/android/client/socket/ChatSocketStateService.kt @@ -197,7 +197,7 @@ internal class ChatSocketStateService(initialState: State = State.Disconnected.S state { onEvent { State.Disconnected.DisconnectedByRequest } onEvent { State.Connecting(it.connectionConf, it.connectionType) } - onEvent { State.RestartConnection } + onEvent { State.RestartConnection(RestartReason.LIFECYCLE_RESUME) } } state { @@ -207,7 +207,7 @@ internal class ChatSocketStateService(initialState: State = State.Disconnected.S onEvent { State.Disconnected.DisconnectedTemporarily(it.error) } onEvent { State.Disconnected.DisconnectedByRequest } onEvent { State.Disconnected.Stopped } - onEvent { State.RestartConnection } + onEvent { State.RestartConnection(RestartReason.NETWORK_AVAILABLE) } } state { @@ -261,6 +261,11 @@ internal class ChatSocketStateService(initialState: State = State.Disconnected.S FORCE_RECONNECTION, } + internal enum class RestartReason { + LIFECYCLE_RESUME, + NETWORK_AVAILABLE, + } + private sealed class Event { /** @@ -322,7 +327,7 @@ internal class ChatSocketStateService(initialState: State = State.Disconnected.S /** * State of socket when connection need to be reestablished. */ - object RestartConnection : State() { override fun toString() = "RestartConnection" } + data class RestartConnection(val reason: RestartReason) : State() /** * State of socket when connection is being establishing. diff --git a/stream-chat-android-client/src/release/java/io/getstream/chat/android/client/di/ChatModule.kt b/stream-chat-android-client/src/release/java/io/getstream/chat/android/client/di/ChatModule.kt index 3dc29e90632..f9fd3169035 100644 --- a/stream-chat-android-client/src/release/java/io/getstream/chat/android/client/di/ChatModule.kt +++ b/stream-chat-android-client/src/release/java/io/getstream/chat/android/client/di/ChatModule.kt @@ -19,6 +19,7 @@ package io.getstream.chat.android.client.di import android.content.Context import androidx.lifecycle.Lifecycle import io.getstream.chat.android.client.api.ChatClientConfig +import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.notifications.handler.NotificationConfig import io.getstream.chat.android.client.notifications.handler.NotificationHandler import io.getstream.chat.android.client.scope.ClientScope @@ -40,6 +41,7 @@ internal class ChatModule( uploader: FileUploader?, tokenManager: TokenManager, customOkHttpClient: OkHttpClient?, + clientDebugger: ChatClientDebugger?, lifecycle: Lifecycle, ) : BaseChatModule( appContext, @@ -51,5 +53,6 @@ internal class ChatModule( uploader, tokenManager, customOkHttpClient, + clientDebugger, lifecycle, ) diff --git a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/socket/experimental/ChatSocketStateServiceTest.kt b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/socket/experimental/ChatSocketStateServiceTest.kt index 45cfe7785f8..342cc8ffac3 100644 --- a/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/socket/experimental/ChatSocketStateServiceTest.kt +++ b/stream-chat-android-client/src/test/java/io/getstream/chat/android/client/socket/experimental/ChatSocketStateServiceTest.kt @@ -19,6 +19,7 @@ package io.getstream.chat.android.client.socket.experimental import io.getstream.chat.android.client.Mother import io.getstream.chat.android.client.events.ConnectedEvent import io.getstream.chat.android.client.socket.ChatSocketStateService +import io.getstream.chat.android.client.socket.ChatSocketStateService.RestartReason import io.getstream.chat.android.client.socket.ChatSocketStateService.State import io.getstream.chat.android.client.socket.SocketFactory import io.getstream.chat.android.randomBoolean @@ -219,8 +220,8 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onNetworkAvailableArgs() = listOf( Arguments.of( - State.RestartConnection, - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), ), State.Connecting(Mother.randomConnectionConf(), Mother.randomConnectionType()).let { Arguments.of( @@ -240,7 +241,7 @@ internal class ChatSocketStateServiceTest { ), Arguments.of( State.Disconnected.NetworkDisconnected, - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), ), Arguments.of( State.Disconnected.WebSocketEventLost, @@ -267,7 +268,7 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onNetworkNotAvailableArgs() = listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), State.Disconnected.NetworkDisconnected, ), Arguments.of( @@ -309,7 +310,7 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onRequiredDisconnectArgs() = listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), State.Disconnected.DisconnectedByRequest, ), Arguments.of( @@ -349,7 +350,7 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onStopArgs() = listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.LIFECYCLE_RESUME), State.Disconnected.Stopped, ), Arguments.of( @@ -391,8 +392,8 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onResumeArgs() = listOf( Arguments.of( - State.RestartConnection, - State.RestartConnection, + State.RestartConnection(RestartReason.LIFECYCLE_RESUME), + State.RestartConnection(RestartReason.LIFECYCLE_RESUME), ), State.Connecting(Mother.randomConnectionConf(), Mother.randomConnectionType()).let { Arguments.of( @@ -408,7 +409,7 @@ internal class ChatSocketStateServiceTest { }, Arguments.of( State.Disconnected.Stopped, - State.RestartConnection, + State.RestartConnection(RestartReason.LIFECYCLE_RESUME), ), Arguments.of( State.Disconnected.NetworkDisconnected, @@ -439,7 +440,7 @@ internal class ChatSocketStateServiceTest { @JvmStatic fun onWebSocketEventLostArgs() = listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), State.Disconnected.WebSocketEventLost, ), Arguments.of( @@ -483,13 +484,13 @@ internal class ChatSocketStateServiceTest { fun onReconnectArgs() = Mother.randomConnectionConf().let { newConnectionConf -> listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), newConnectionConf, true, State.Connecting(newConnectionConf, ChatSocketStateService.ConnectionType.FORCE_RECONNECTION), ), Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), newConnectionConf, false, State.Connecting(newConnectionConf, ChatSocketStateService.ConnectionType.AUTOMATIC_RECONNECTION), @@ -597,7 +598,7 @@ internal class ChatSocketStateServiceTest { fun onConnectionEstablishedArgs() = Mother.randomConnectedEvent().let { connectedEvent -> listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), connectedEvent, State.Connected(connectedEvent), ), @@ -652,7 +653,7 @@ internal class ChatSocketStateServiceTest { fun onUnrecoverableErrorArgs() = randomChatNetworkError().let { error -> listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), error, State.Disconnected.DisconnectedPermanently(error), ), @@ -705,7 +706,7 @@ internal class ChatSocketStateServiceTest { fun onNetworkErrorArgs() = randomChatNetworkError().let { error -> listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), error, State.Disconnected.DisconnectedTemporarily(error), ), @@ -758,7 +759,7 @@ internal class ChatSocketStateServiceTest { fun onConnectArgs() = Mother.randomConnectionConf().let { newConnectionConf -> listOf( Arguments.of( - State.RestartConnection, + State.RestartConnection(RestartReason.NETWORK_AVAILABLE), newConnectionConf, State.Connecting(newConnectionConf, ChatSocketStateService.ConnectionType.INITIAL_CONNECTION), ), diff --git a/stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/client/docusaurus/Debugging.java b/stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/client/docusaurus/Debugging.java index 858b00265b2..752f6b104fa 100644 --- a/stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/client/docusaurus/Debugging.java +++ b/stream-chat-android-docs/src/main/java/io/getstream/chat/docs/java/client/docusaurus/Debugging.java @@ -8,6 +8,7 @@ import io.getstream.chat.android.client.debugger.ChatClientDebugger; import io.getstream.chat.android.client.debugger.SendMessageDebugger; import io.getstream.chat.android.models.Message; +import io.getstream.result.Error; import io.getstream.result.Result; /** @@ -18,6 +19,11 @@ public class Debugging { public void addClientDebugger(@NonNull Context context) { final ChatClient chatClient = new ChatClient.Builder("apiKey", context) .clientDebugger(new ChatClientDebugger() { + @Override + public void onNonFatalErrorOccurred(@NonNull String tag, @NonNull String src, @NonNull String desc, @NonNull Error error) { + // TODO: Implement your custom logic here + } + @NonNull @Override public SendMessageDebugger debugSendMessage( diff --git a/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/client/docusaurus/Debugging.kt b/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/client/docusaurus/Debugging.kt index 0897d7cb254..5262619a140 100644 --- a/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/client/docusaurus/Debugging.kt +++ b/stream-chat-android-docs/src/main/kotlin/io/getstream/chat/docs/kotlin/client/docusaurus/Debugging.kt @@ -5,6 +5,7 @@ import io.getstream.chat.android.client.ChatClient import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.debugger.SendMessageDebugger import io.getstream.chat.android.models.Message +import io.getstream.result.Error import io.getstream.result.Result @@ -16,6 +17,10 @@ class Debugging { fun addClientDebugger(context: Context) { val client = ChatClient.Builder("apiKey", context) .clientDebugger(object : ChatClientDebugger { + override fun onNonFatalErrorOccurred(tag: String, src: String, desc: String, error: Error) { + // TODO: Implement your custom logic here + } + override fun debugSendMessage( channelType: String, channelId: String, diff --git a/stream-chat-android-ui-components-sample/detekt-baseline.xml b/stream-chat-android-ui-components-sample/detekt-baseline.xml index ed22e377c7b..1618f942b90 100644 --- a/stream-chat-android-ui-components-sample/detekt-baseline.xml +++ b/stream-chat-android-ui-components-sample/detekt-baseline.xml @@ -3,6 +3,7 @@ ComplexCondition:UserRepository.kt$UserRepository$apiKey != null && id != null && name != null && token != null && image != null + ForbiddenComment:CustomChatClientDebugger.kt$CustomChatClientDebugger$// TODO: Implement your custom logic here LongMethod:ChatFragment.kt$ChatFragment$private fun initMessageListViewModel() LongMethod:ComponentBrowserAvatarViewFragment.kt$ComponentBrowserAvatarViewFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?) LongMethod:ComponentBrowserViewReactionsFragment.kt$ComponentBrowserViewReactionsFragment$override fun onViewCreated(view: View, savedInstanceState: Bundle?) diff --git a/stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/debugger/CustomChatClientDebugger.kt b/stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/debugger/CustomChatClientDebugger.kt index 1f344cda770..4afc6653f61 100644 --- a/stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/debugger/CustomChatClientDebugger.kt +++ b/stream-chat-android-ui-components-sample/src/main/kotlin/io/getstream/chat/ui/sample/debugger/CustomChatClientDebugger.kt @@ -20,10 +20,15 @@ import io.getstream.chat.android.client.debugger.ChatClientDebugger import io.getstream.chat.android.client.debugger.SendMessageDebugger import io.getstream.chat.android.models.Message import io.getstream.log.taggedLogger +import io.getstream.result.Error import io.getstream.result.Result class CustomChatClientDebugger : ChatClientDebugger { + override fun onNonFatalErrorOccurred(tag: String, src: String, desc: String, error: Error) { + // TODO: Implement your custom logic here + } + override fun debugSendMessage( channelType: String, channelId: String,