From 81e06dc1d8d2a574a473f2c8c8b22a19a13752d8 Mon Sep 17 00:00:00 2001 From: Kirill Kamakin Date: Fri, 5 Aug 2022 21:54:52 +0200 Subject: [PATCH] Simplify logAndMapErrors calls --- .../data/add/impl/AddRecipeDataSourceImpl.kt | 3 +-- .../data/auth/impl/AuthDataSourceImpl.kt | 9 ++++--- .../baseurl/impl/VersionDataSourceImpl.kt | 3 +-- .../mealient/extensions/NetworkExtensions.kt | 25 ++++++++----------- 4 files changed, 17 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt index 7799b79..46f7f8c 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/add/impl/AddRecipeDataSourceImpl.kt @@ -17,8 +17,7 @@ class AddRecipeDataSourceImpl @Inject constructor( override suspend fun addRecipe(recipe: AddRecipeRequest): String { logger.v { "addRecipe() called with: recipe = $recipe" } val service = addRecipeServiceFactory.provideService() - val response = logAndMapErrors( - logger, + val response = logger.logAndMapErrors( block = { service.addRecipe(recipe) }, logProvider = { "addRecipe: can't add recipe" } ) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt index 3af42d0..30f4011 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/auth/impl/AuthDataSourceImpl.kt @@ -5,7 +5,7 @@ import gq.kirmanak.mealient.data.network.ErrorDetail import gq.kirmanak.mealient.data.network.NetworkError.NotMealie import gq.kirmanak.mealient.data.network.NetworkError.Unauthorized import gq.kirmanak.mealient.data.network.ServiceFactory -import gq.kirmanak.mealient.extensions.decodeErrorBodyOrNull +import gq.kirmanak.mealient.extensions.decodeErrorBody import gq.kirmanak.mealient.extensions.logAndMapErrors import gq.kirmanak.mealient.logging.Logger import kotlinx.serialization.json.Json @@ -34,8 +34,7 @@ class AuthDataSourceImpl @Inject constructor( authService: AuthService, username: String, password: String - ): Response = logAndMapErrors( - logger, + ): Response = logger.logAndMapErrors( block = { authService.getToken(username = username, password = password) }, logProvider = { "sendRequest: can't get token" }, ) @@ -46,7 +45,9 @@ class AuthDataSourceImpl @Inject constructor( response.body()?.accessToken ?: throw NotMealie(NullPointerException("Body is null")) } else { val cause = HttpException(response) - val errorDetail: ErrorDetail? = response.decodeErrorBodyOrNull(json, logger) + val errorDetail = json.runCatching { decodeErrorBody(response) } + .onFailure { logger.e(it) { "Can't decode error body" } } + .getOrNull() throw when (errorDetail?.detail) { "Unauthorized" -> Unauthorized(cause) else -> NotMealie(cause) diff --git a/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt b/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt index 6493395..62ce4cd 100644 --- a/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt +++ b/app/src/main/java/gq/kirmanak/mealient/data/baseurl/impl/VersionDataSourceImpl.kt @@ -19,8 +19,7 @@ class VersionDataSourceImpl @Inject constructor( logger.v { "getVersionInfo() called with: baseUrl = $baseUrl" } val service = serviceFactory.provideService(baseUrl) - val response = logAndMapErrors( - logger, + val response = logger.logAndMapErrors( block = { service.getVersion() }, logProvider = { "getVersionInfo: can't request version" } ) diff --git a/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt b/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt index 6c636f8..1327d57 100644 --- a/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt +++ b/app/src/main/java/gq/kirmanak/mealient/extensions/NetworkExtensions.kt @@ -8,28 +8,23 @@ import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import retrofit2.HttpException import retrofit2.Response -import java.io.InputStream - -inline fun Response.decodeErrorBodyOrNull(json: Json, logger: Logger): R? = - errorBody()?.byteStream()?.let { json.decodeFromStreamOrNull(it, logger) } @OptIn(ExperimentalSerializationApi::class) -inline fun Json.decodeFromStreamOrNull(stream: InputStream, logger: Logger): T? = - runCatching { decodeFromStream(stream) } - .onFailure { logger.e(it) { "decodeFromStreamOrNull: can't decode" } } - .getOrNull() +inline fun Json.decodeErrorBody(response: Response): R = + checkNotNull(response.errorBody()) { "Can't decode absent error body" } + .byteStream() + .let(::decodeFromStream) + fun Throwable.mapToNetworkError(): NetworkError = when (this) { is HttpException, is SerializationException -> NetworkError.NotMealie(this) else -> NetworkError.NoServerConnection(this) } -inline fun logAndMapErrors( - logger: Logger, +inline fun Logger.logAndMapErrors( block: () -> T, noinline logProvider: () -> String -): T = - runCatchingExceptCancel(block).getOrElse { - logger.e(it, messageSupplier = logProvider) - throw it.mapToNetworkError() - } \ No newline at end of file +): T = runCatchingExceptCancel(block).getOrElse { + e(it, messageSupplier = logProvider) + throw it.mapToNetworkError() +} \ No newline at end of file