From a9b8b5830bd5d3a6e3df050c3725ff34090af57f Mon Sep 17 00:00:00 2001 From: josephj Date: Wed, 18 Oct 2023 11:08:11 +0200 Subject: [PATCH] Improve error handling and logging for analytics and image loader --- .../checkout/core/exception/HttpException.kt | 6 +-- .../core/internal/data/api/OkHttpClient.kt | 40 +++++++++++++------ .../internal/data/model/ErrorResponseBody.kt | 8 ++-- .../data/api/DefaultAnalyticsRepository.kt | 3 +- .../internal/ui/ImageLoadingExtensions.kt | 2 +- 5 files changed, 38 insertions(+), 21 deletions(-) diff --git a/checkout-core/src/main/java/com/adyen/checkout/core/exception/HttpException.kt b/checkout-core/src/main/java/com/adyen/checkout/core/exception/HttpException.kt index 7a9eb2c87b..26058a7b8a 100644 --- a/checkout-core/src/main/java/com/adyen/checkout/core/exception/HttpException.kt +++ b/checkout-core/src/main/java/com/adyen/checkout/core/exception/HttpException.kt @@ -14,7 +14,7 @@ import com.adyen.checkout.core.internal.data.model.ErrorResponseBody * Indicates that an internal API call has failed. */ class HttpException( - val code: Int, - override val message: String, + code: Int, + message: String, val errorBody: ErrorResponseBody?, -) : CheckoutException(message) +) : CheckoutException("$code $message") diff --git a/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/api/OkHttpClient.kt b/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/api/OkHttpClient.kt index 738bcf3a23..4434c8c3e8 100644 --- a/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/api/OkHttpClient.kt +++ b/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/api/OkHttpClient.kt @@ -83,8 +83,11 @@ internal class OkHttpClient( response.body?.close() return bytes } else { - val errorBody = response.errorBody() - val exception = HttpException(response.code, response.message, errorBody) + val exception = HttpException( + code = response.code, + message = response.message, + errorBody = response.errorBody() + ) response.body?.close() throw exception } @@ -98,16 +101,29 @@ internal class OkHttpClient( (defaultHeaders + this).toHeaders() @Suppress("SwallowedException") - private fun Response.errorBody(): ErrorResponseBody? = try { - body?.string() - ?.let { JSONObject(it) } - ?.let { ErrorResponseBody.SERIALIZER.deserialize(it) } - } catch (e: IOException) { - null - } catch (e: JSONException) { - null - } catch (e: ModelSerializationException) { - null + private fun Response.errorBody(): ErrorResponseBody? { + val stringBody = try { + body?.string() + } catch (e: IOException) { + null + } + + val parsedErrorResponseBody = try { + stringBody + ?.let { JSONObject(it) } + ?.let { ErrorResponseBody.SERIALIZER.deserialize(it) } + } catch (e: JSONException) { + null + } catch (e: ModelSerializationException) { + null + } + + return parsedErrorResponseBody ?: ErrorResponseBody( + status = null, + errorCode = null, + message = stringBody, + errorType = null, + ) } companion object { diff --git a/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/model/ErrorResponseBody.kt b/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/model/ErrorResponseBody.kt index a1a4fb5237..54ab2d68e4 100644 --- a/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/model/ErrorResponseBody.kt +++ b/checkout-core/src/main/java/com/adyen/checkout/core/internal/data/model/ErrorResponseBody.kt @@ -17,10 +17,10 @@ import org.json.JSONObject @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) @Parcelize data class ErrorResponseBody( - val status: Int, - val errorCode: String, - val message: String, - val errorType: String, + val status: Int?, + val errorCode: String?, + val message: String?, + val errorType: String?, ) : ModelObject() { companion object { diff --git a/components-core/src/main/java/com/adyen/checkout/components/core/internal/data/api/DefaultAnalyticsRepository.kt b/components-core/src/main/java/com/adyen/checkout/components/core/internal/data/api/DefaultAnalyticsRepository.kt index de206c393f..922cc5718b 100644 --- a/components-core/src/main/java/com/adyen/checkout/components/core/internal/data/api/DefaultAnalyticsRepository.kt +++ b/components-core/src/main/java/com/adyen/checkout/components/core/internal/data/api/DefaultAnalyticsRepository.kt @@ -58,7 +58,8 @@ class DefaultAnalyticsRepository( Logger.v(TAG, "Analytics setup call successful") }.onFailure { e -> state = State.Failed - Logger.e(TAG, "Failed to send analytics setup call", e) + // TODO change back to error when all analytic endpoints are live + Logger.w(TAG, "Failed to send analytics setup call - ${e::class.simpleName}: ${e.message}") } } diff --git a/ui-core/src/main/java/com/adyen/checkout/ui/core/internal/ui/ImageLoadingExtensions.kt b/ui-core/src/main/java/com/adyen/checkout/ui/core/internal/ui/ImageLoadingExtensions.kt index 5c60f04d4b..67bb0223df 100644 --- a/ui-core/src/main/java/com/adyen/checkout/ui/core/internal/ui/ImageLoadingExtensions.kt +++ b/ui-core/src/main/java/com/adyen/checkout/ui/core/internal/ui/ImageLoadingExtensions.kt @@ -60,7 +60,7 @@ fun ImageView.load( url, onSuccess = { setImageBitmap(it) }, onError = { e -> - Logger.e(TAG, "Failed loading image for $url", e) + Logger.w(TAG, "Failed loading image for $url - ${e::class.simpleName}: ${e.message}") setImageResource(errorFallback) } )