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
56 changes: 51 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ buildscript {
}

dependencies {
classpath "dev.icerock.moko:network-generator:0.22.0"
classpath "dev.icerock.moko:network-generator:0.23.0"
}
}

Expand All @@ -53,10 +53,10 @@ project build.gradle
apply plugin: "dev.icerock.mobile.multiplatform-network-generator"

dependencies {
commonMainApi("dev.icerock.moko:network:0.22.0")
commonMainApi("dev.icerock.moko:network-engine:0.22.0") // configured HttpClientEngine
commonMainApi("dev.icerock.moko:network-bignum:0.22.0") // kbignum serializer
commonMainApi("dev.icerock.moko:network-errors:0.22.0") // moko-errors integration
commonMainApi("dev.icerock.moko:network:0.23.0")
commonMainApi("dev.icerock.moko:network-engine:0.23.0") // configured HttpClientEngine
commonMainApi("dev.icerock.moko:network-bignum:0.23.0") // kbignum serializer
commonMainApi("dev.icerock.moko:network-errors:0.23.0") // moko-errors integration
}
```

Expand Down Expand Up @@ -175,6 +175,52 @@ viewModelScope.launch {
}
```

#### Customizing error texts

You can override standard error messages (which are localized in English and Russian by default) by
passing your own NetworkErrorsTexts object. This allows you to customize messages for HTTP errors,
SSL issues, serialization failures, and set a fallback defaultErrorText.

Usage example:

```kotlin
// 1. Define HTTP specific errors
private val httpNetworkErrorsTexts = HttpNetworkErrorsTexts(
unauthorizedErrorText = MR.strings.unauthorizedErrorText,
notFoundErrorText = MR.strings.notFoundErrorText,
accessDeniedErrorText = MR.strings.accessDeniedErrorText,
internalServerErrorText = MR.strings.internalServerErrorText
)

// 2. Define SSL specific errors
private val sslNetworkErrorsTexts = SSLNetworkErrorsTexts(
secureConnectionFailed = MR.strings.secureConnectionFailedText,
serverCertificateHasBadDate = MR.strings.serverCertificateHasBadDateText,
serverCertificateUntrusted = MR.strings.serverCertificateUntrustedText,
serverCertificateHasUnknownRoot = MR.strings.serverCertificateHasUnknownRootText,
serverCertificateNotYetValid = MR.strings.serverCertificateNotYetValidText,
clientCertificateRejected = MR.strings.clientCertificateRejectedText,
clientCertificateRequired = MR.strings.clientCertificateRequiredText,
cannotLoadFromNetwork = MR.strings.cannotLoadFromNetworkText
)

// 3. Assemble all texts including general network errors and default fallback
private val networkErrorsTexts = NetworkErrorsTexts(
networkConnectionErrorText = MR.strings.networkConnectionErrorText,
serializationErrorText = MR.strings.serializationErrorText,
httpNetworkErrorsTexts = httpNetworkErrorsTexts,
sslNetworkErrorsTexts = sslNetworkErrorsTexts,
defaultErrorText = MR.strings.defaultErrorText // Fallback for undefined errors
)

// 4. Register mappers with your custom texts
fun initExceptionMappersStorage() {
ExceptionMappersStorage.registerAllNetworkMappers(
errorsTexts = networkErrorsTexts
)
}
```

For more information about exception handling see [moko-errors](https://github.com/icerockdev/moko-errors).

## Samples
Expand Down
2 changes: 2 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ kotlin.mpp.applyDefaultHierarchyTemplate=false
android.useAndroidX=true

mobile.multiplatform.iosTargetWarning=false
mobile.multiplatform.useIosShortcut=false
moko.resources.disableStaticFrameworkWarning=true

xcodeproj=./sample/ios-app

Expand Down
8 changes: 4 additions & 4 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[versions]
kotlinVersion = "2.0.20"
kotlinVersion = "2.1.0"

# android
lifecycleViewModelVersion = "2.6.1"
Expand All @@ -16,11 +16,11 @@ kotlinxSerializationVersion = "1.7.3"
coroutinesVersion = "1.9.0"

# moko
mokoResourcesVersion = "0.24.4"
mokoResourcesVersion = "0.26.0"
mokoMvvmVersion = "0.16.0"
mokoErrorsVersion = "0.7.0"
mokoErrorsVersion = "0.9.0"
mokoTestVersion = "0.6.1"
mokoNetworkVersion = "0.22.0"
mokoNetworkVersion = "0.23.0"

# tests
espressoCoreVersion = "3.5.1"
Expand Down
4 changes: 4 additions & 0 deletions network-bignum/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ android {

kotlin {
jvm()

compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}

dependencies {
Expand Down
4 changes: 4 additions & 0 deletions network-engine/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ kotlin {
dependsOn(commonJvmAndroid)
}
}

compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}

dependencies {
Expand Down
6 changes: 6 additions & 0 deletions network-errors/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ android {
namespace = "dev.icerock.moko.network.errors"
}

kotlin {
compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}

dependencies {
commonMainImplementation(libs.kotlinSerialization)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
package dev.icerock.moko.network.errors

import dev.icerock.moko.resources.StringResource
import dev.icerock.moko.errors.MR as ErrorsMR

data class NetworkErrorsTexts(
val networkConnectionErrorText: StringResource = MR.strings.networkConnectionErrorText,
val serializationErrorText: StringResource = MR.strings.serializationErrorText,
val httpNetworkErrorsTexts: HttpNetworkErrorsTexts = HttpNetworkErrorsTexts(),
val sslNetworkErrorsTexts: SSLNetworkErrorsTexts = SSLNetworkErrorsTexts()
val sslNetworkErrorsTexts: SSLNetworkErrorsTexts = SSLNetworkErrorsTexts(),
val defaultErrorText: StringResource = ErrorsMR.strings.moko_errors_unknownError,
)

data class HttpNetworkErrorsTexts(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@

package dev.icerock.moko.network.errors

import dev.icerock.moko.errors.MR
import dev.icerock.moko.errors.mappers.ExceptionMappersStorage
import dev.icerock.moko.network.SSLExceptionType
import dev.icerock.moko.network.exceptions.ErrorException
import dev.icerock.moko.network.exceptions.ValidationException
import dev.icerock.moko.network.getSSLExceptionType
import dev.icerock.moko.network.isNetworkConnectionError
import dev.icerock.moko.network.isSSLException
import dev.icerock.moko.resources.StringResource
import dev.icerock.moko.resources.desc.CompositionStringDesc
import dev.icerock.moko.resources.desc.ResourceFormatted
import dev.icerock.moko.resources.desc.StringDesc
Expand All @@ -36,6 +36,7 @@ fun ExceptionMappersStorage.registerAllNetworkMappers(
mapper = {
getSSLExceptionStringDescMapper(
sslException = it,
defaultErrorText = errorsTexts.defaultErrorText,
sslNetworkErrorsTexts = errorsTexts.sslNetworkErrorsTexts
)
}
Expand All @@ -45,6 +46,7 @@ fun ExceptionMappersStorage.registerAllNetworkMappers(
).register<ErrorException, StringDesc> {
getNetworkErrorExceptionStringDescMapper(
errorException = it,
defaultErrorText = errorsTexts.defaultErrorText,
httpNetworkErrorsTexts = errorsTexts.httpNetworkErrorsTexts
)
}.register(::validationExceptionStringDescMapper)
Expand All @@ -55,6 +57,7 @@ fun ExceptionMappersStorage.registerAllNetworkMappers(
*/
private fun getNetworkErrorExceptionStringDescMapper(
errorException: ErrorException,
defaultErrorText: StringResource,
httpNetworkErrorsTexts: HttpNetworkErrorsTexts
): StringDesc {
val httpStatusCode = errorException.httpStatusCode
Expand All @@ -69,7 +72,7 @@ private fun getNetworkErrorExceptionStringDescMapper(
)
}

else -> MR.strings.moko_errors_unknownError.desc()
else -> defaultErrorText.desc()
}
}

Expand All @@ -79,6 +82,7 @@ private fun getNetworkErrorExceptionStringDescMapper(
@Suppress("ComplexMethod")
private fun getSSLExceptionStringDescMapper(
sslException: Throwable,
defaultErrorText: StringResource,
sslNetworkErrorsTexts: SSLNetworkErrorsTexts
): StringDesc {
return when (sslException.getSSLExceptionType()) {
Expand All @@ -90,7 +94,7 @@ private fun getSSLExceptionStringDescMapper(
SSLExceptionType.ClientCertificateRejected -> sslNetworkErrorsTexts.clientCertificateRejected.desc()
SSLExceptionType.ClientCertificateRequired -> sslNetworkErrorsTexts.clientCertificateRequired.desc()
SSLExceptionType.CannotLoadFromNetwork -> sslNetworkErrorsTexts.cannotLoadFromNetwork.desc()
else -> MR.strings.moko_errors_unknownError.desc()
else -> defaultErrorText.desc()
}
}

Expand Down
4 changes: 4 additions & 0 deletions network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ kotlin {
}
}
}

compilerOptions {
freeCompilerArgs.add("-Xexpect-actual-classes")
}
}

dependencies {
Expand Down
4 changes: 2 additions & 2 deletions sample/mpp-library/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ plugins {
id("dev.icerock.moko.gradle.android.base")
id("org.jetbrains.kotlin.multiplatform")
id("org.jetbrains.kotlin.plugin.serialization")
id("dev.icerock.mobile.multiplatform.targets")
id("dev.icerock.moko.gradle.multiplatform.mobile")
id("dev.icerock.mobile.multiplatform.ios-framework")
id("dev.icerock.mobile.multiplatform-resources")
id("dev.icerock.mobile.multiplatform-network-generator")
id("dev.icerock.mobile.multiplatform.ios-framework")
id("dev.icerock.moko.gradle.detekt")
id("dev.icerock.moko.gradle.tests")
}
Expand Down