From 986bc303837041389590875911cadf2045698e9e Mon Sep 17 00:00:00 2001 From: Satoshi Qazi Muhammed Date: Wed, 4 Nov 2026 05:18:00 +0400 Subject: [PATCH] Log Wallet Connect init failures; give empty network errors a text - Wallet Connect core and Web3Wallet initialization errors were swallowed silently; log them. A retry is not added: initialization fails only on bad configuration, and the relay connects later on demand. - NovaException.networkError carried an empty message; it now uses the existing translated connection error text. The unused NovaException.unexpectedError is removed. - BaseException.unexpectedError fell back to an empty message when the exception had none; HttpExceptionHandler now passes the translated common error text as the fallback. - Remove the unused AccountRepository.getMyAccounts stub. --- .../java/io/novafoundation/nova/app/App.kt | 8 +++- .../nova/common/base/BaseException.kt | 4 +- .../nova/common/base/errors/NovaException.kt | 7 +-- .../data/network/HttpExceptionHandler.kt | 2 +- .../data/network/HttpExceptionHandlerTest.kt | 46 +++++++++++++++++++ .../domain/interfaces/AccountRepository.kt | 2 - .../data/repository/AccountRepositoryImpl.kt | 10 ---- 7 files changed, 57 insertions(+), 22 deletions(-) create mode 100644 common/src/test/java/io/novafoundation/nova/common/data/network/HttpExceptionHandlerTest.kt diff --git a/app/src/main/java/io/novafoundation/nova/app/App.kt b/app/src/main/java/io/novafoundation/nova/app/App.kt index c3b177b3..0842a518 100644 --- a/app/src/main/java/io/novafoundation/nova/app/App.kt +++ b/app/src/main/java/io/novafoundation/nova/app/App.kt @@ -3,6 +3,7 @@ package io.novafoundation.nova.app import android.app.Application import android.content.Context import android.content.res.Configuration +import android.util.Log import com.walletconnect.android.Core import com.walletconnect.android.CoreClient import com.walletconnect.android.relay.ConnectionType @@ -14,6 +15,7 @@ import io.novafoundation.nova.common.di.CommonApi import io.novafoundation.nova.common.di.FeatureContainer import io.novafoundation.nova.common.resources.ContextManager import io.novafoundation.nova.common.resources.LanguagesHolder +import io.novafoundation.nova.common.utils.LOG_TAG import io.novafoundation.nova.common.utils.coroutines.RootScope import io.novafoundation.nova.feature_wallet_connect_impl.BuildConfig import javax.inject.Inject @@ -85,13 +87,15 @@ open class App : Application(), FeatureContainer { ) CoreClient.initialize(relayServerUrl = serverUrl, connectionType = connectionType, application = this, metaData = appMetaData) { error -> - // TODO maybe re-initialize client + // Initialization fails only on bad configuration (project id, metadata), which a retry would not fix. + // The relay itself connects later, on demand, in RealWalletConnectService + Log.e(LOG_TAG, "Failed to initialize Wallet Connect core", error.throwable) } val initParams = Wallet.Params.Init(core = CoreClient) Web3Wallet.initialize(initParams) { error -> - // TODO maybe re-initialize client + Log.e(LOG_TAG, "Failed to initialize Web3Wallet", error.throwable) } } } diff --git a/common/src/main/java/io/novafoundation/nova/common/base/BaseException.kt b/common/src/main/java/io/novafoundation/nova/common/base/BaseException.kt index 099961ef..c7a25875 100644 --- a/common/src/main/java/io/novafoundation/nova/common/base/BaseException.kt +++ b/common/src/main/java/io/novafoundation/nova/common/base/BaseException.kt @@ -29,8 +29,8 @@ class BaseException( return BaseException(Kind.NETWORK, message, exception) } - fun unexpectedError(exception: Throwable): BaseException { - return BaseException(Kind.UNEXPECTED, exception.message ?: "", exception) + fun unexpectedError(fallbackMessage: String, exception: Throwable): BaseException { + return BaseException(Kind.UNEXPECTED, exception.message ?: fallbackMessage, exception) } } } diff --git a/common/src/main/java/io/novafoundation/nova/common/base/errors/NovaException.kt b/common/src/main/java/io/novafoundation/nova/common/base/errors/NovaException.kt index f99b2286..414dbd33 100644 --- a/common/src/main/java/io/novafoundation/nova/common/base/errors/NovaException.kt +++ b/common/src/main/java/io/novafoundation/nova/common/base/errors/NovaException.kt @@ -1,5 +1,6 @@ package io.novafoundation.nova.common.base.errors +import io.novafoundation.nova.common.R import io.novafoundation.nova.common.resources.ResourceManager class NovaException( @@ -16,11 +17,7 @@ class NovaException( companion object { fun networkError(resourceManager: ResourceManager, throwable: Throwable): NovaException { - return NovaException(Kind.NETWORK, "", throwable) // TODO: add common error text to resources - } - - fun unexpectedError(exception: Throwable): NovaException { - return NovaException(Kind.UNEXPECTED, exception.message ?: "", exception) // TODO: add common error text to resources + return NovaException(Kind.NETWORK, resourceManager.getString(R.string.connection_error_message_v2_2_0), throwable) } } } diff --git a/common/src/main/java/io/novafoundation/nova/common/data/network/HttpExceptionHandler.kt b/common/src/main/java/io/novafoundation/nova/common/data/network/HttpExceptionHandler.kt index cab249c9..dfb2ee59 100644 --- a/common/src/main/java/io/novafoundation/nova/common/data/network/HttpExceptionHandler.kt +++ b/common/src/main/java/io/novafoundation/nova/common/data/network/HttpExceptionHandler.kt @@ -28,7 +28,7 @@ class HttpExceptionHandler( BaseException.httpError(errorCode, resourceManager.getString(R.string.common_undefined_error_message)) } is IOException -> BaseException.networkError(resourceManager.getString(R.string.connection_error_message_v2_2_0), exception) - else -> BaseException.unexpectedError(exception) + else -> BaseException.unexpectedError(resourceManager.getString(R.string.common_undefined_error_message), exception) } } } diff --git a/common/src/test/java/io/novafoundation/nova/common/data/network/HttpExceptionHandlerTest.kt b/common/src/test/java/io/novafoundation/nova/common/data/network/HttpExceptionHandlerTest.kt new file mode 100644 index 00000000..b8666713 --- /dev/null +++ b/common/src/test/java/io/novafoundation/nova/common/data/network/HttpExceptionHandlerTest.kt @@ -0,0 +1,46 @@ +package io.novafoundation.nova.common.data.network + +import io.novafoundation.nova.common.R +import io.novafoundation.nova.common.base.BaseException +import io.novafoundation.nova.common.base.errors.NovaException +import io.novafoundation.nova.common.resources.ResourceManager +import org.junit.Assert.assertEquals +import org.junit.Test +import org.mockito.Mockito +import java.io.IOException + +class HttpExceptionHandlerTest { + + private val resourceManager = Mockito.mock(ResourceManager::class.java).also { + Mockito.`when`(it.getString(R.string.common_undefined_error_message)).thenReturn(UNDEFINED) + Mockito.`when`(it.getString(R.string.connection_error_message_v2_2_0)).thenReturn(CONNECTION) + } + + private val handler = HttpExceptionHandler(resourceManager) + + @Test + fun `an unexpected error without a message gets the common error text`() { + val error = handler.transformException(IllegalStateException()) + + assertEquals(BaseException.Kind.UNEXPECTED, error.kind) + assertEquals(UNDEFINED, error.message) + } + + @Test + fun `an unexpected error keeps its own message`() { + assertEquals("boom", handler.transformException(IllegalStateException("boom")).message) + } + + @Test + fun `a socket network error carries the connection error text`() { + val error = NovaException.networkError(resourceManager, IOException()) + + assertEquals(NovaException.Kind.NETWORK, error.kind) + assertEquals(CONNECTION, error.message) + } + + private companion object { + const val UNDEFINED = "undefined" + const val CONNECTION = "connection" + } +} diff --git a/feature-account-api/src/main/java/io/novafoundation/nova/feature_account_api/domain/interfaces/AccountRepository.kt b/feature-account-api/src/main/java/io/novafoundation/nova/feature_account_api/domain/interfaces/AccountRepository.kt index 16312de8..51d2dd1f 100644 --- a/feature-account-api/src/main/java/io/novafoundation/nova/feature_account_api/domain/interfaces/AccountRepository.kt +++ b/feature-account-api/src/main/java/io/novafoundation/nova/feature_account_api/domain/interfaces/AccountRepository.kt @@ -68,8 +68,6 @@ interface AccountRepository { suspend fun getAccountOrNull(address: String): Account? - suspend fun getMyAccounts(query: String, chainId: String): Set - suspend fun isCodeSet(): Boolean suspend fun savePinCode(code: String) diff --git a/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/repository/AccountRepositoryImpl.kt b/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/repository/AccountRepositoryImpl.kt index 87373dda..25676264 100644 --- a/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/repository/AccountRepositoryImpl.kt +++ b/feature-account-impl/src/main/java/io/novafoundation/nova/feature_account_impl/data/repository/AccountRepositoryImpl.kt @@ -193,16 +193,6 @@ class AccountRepositoryImpl( return accountDao.getAccount(address)?.let { mapAccountLocalToAccount(it) } } - override suspend fun getMyAccounts(query: String, chainId: String): Set { -// return withContext(Dispatchers.Default) { -// accountDao.getAccounts(query, networkType) -// .map { mapAccountLocalToAccount(it) } -// .toSet() -// } - - return emptySet() // TODO wallet - } - override suspend fun isCodeSet(): Boolean { return accountDataSource.getPinCode() != null }