diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/http/CwaWebException.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/http/CwaWebException.kt index fc89eff4627de3bd0fb3069f8937876563fb0341..7f8d7b4ae755482bc1d80ca7a1d4ce85bd243010 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/http/CwaWebException.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/exception/http/CwaWebException.kt @@ -3,46 +3,77 @@ package de.rki.coronawarnapp.exception.http import de.rki.coronawarnapp.exception.reporting.ErrorCodes import de.rki.coronawarnapp.exception.reporting.ReportedIOException -open class CwaWebException(val statusCode: Int) : ReportedIOException( - ErrorCodes.CWA_WEB_REQUEST_PROBLEM.code, "error during web request, http status $statusCode" +open class CwaWebException( + val statusCode: Int, + message: String?, + cause: Throwable? = null +) : ReportedIOException( + code = ErrorCodes.CWA_WEB_REQUEST_PROBLEM.code, + message = "Error during web request: code=$statusCode message=$message", + cause = cause ) -open class CwaServerError(statusCode: Int) : CwaWebException(statusCode) { +open class CwaServerError( + statusCode: Int, + message: String?, + cause: Throwable? = null +) : CwaWebException( + statusCode = statusCode, + message = message, + cause = cause +) { init { - if (statusCode !in 500..599) - throw IllegalArgumentException("a server error has to have code 5xx") + if (statusCode !in 500..599) { + throw IllegalArgumentException("Invalid HTTP server error code $statusCode (!= 5xx)") + } } } -open class CwaClientError(statusCode: Int) : CwaWebException(statusCode) { +open class CwaClientError( + statusCode: Int, + message: String?, + cause: Throwable? = null +) : CwaWebException( + statusCode = statusCode, + message = message, + cause = cause +) { init { - if (statusCode !in 400..499) - throw IllegalArgumentException("a client error has to have code 4xx") + if (statusCode !in 400..499) { + throw IllegalArgumentException("Invalid HTTP client error code $statusCode (!= 4xx)") + } } } -open class CwaSuccessResponseWithCodeMismatchNotSupportedError(statusCode: Int) : - CwaWebException(statusCode) - -open class CwaInformationalNotSupportedError(statusCode: Int) : CwaWebException(statusCode) -open class CwaRedirectNotSupportedError(statusCode: Int) : CwaWebException(statusCode) - -class BadRequestException : CwaClientError(400) -class UnauthorizedException : CwaClientError(401) -class ForbiddenException : CwaClientError(403) -class NotFoundException : CwaClientError(404) -class ConflictException : CwaClientError(409) -class GoneException : CwaClientError(410) -class UnsupportedMediaTypeException : CwaClientError(415) -class TooManyRequestsException : CwaClientError(429) - -class InternalServerErrorException : CwaServerError(500) -class NotImplementedException : CwaServerError(501) -class BadGatewayException : CwaServerError(502) -class ServiceUnavailableException : CwaServerError(503) -class GatewayTimeoutException : CwaServerError(504) -class HTTPVersionNotSupported : CwaServerError(505) -class NetworkAuthenticationRequiredException : CwaServerError(511) -class CwaUnknownHostException : CwaServerError(597) -class NetworkReadTimeoutException : CwaServerError(598) -class NetworkConnectTimeoutException : CwaServerError(599) +open class CwaSuccessResponseWithCodeMismatchNotSupportedError(statusCode: Int, message: String?) : + CwaWebException(statusCode, message) + +open class CwaInformationalNotSupportedError(statusCode: Int, message: String?) : CwaWebException(statusCode, message) +open class CwaRedirectNotSupportedError(statusCode: Int, message: String?) : CwaWebException(statusCode, message) + +class BadRequestException(message: String?) : CwaClientError(400, message) +class UnauthorizedException(message: String?) : CwaClientError(401, message) +class ForbiddenException(message: String?) : CwaClientError(403, message) +class NotFoundException(message: String?) : CwaClientError(404, message) +class ConflictException(message: String?) : CwaClientError(409, message) +class GoneException(message: String?) : CwaClientError(410, message) +class UnsupportedMediaTypeException(message: String?) : CwaClientError(415, message) +class TooManyRequestsException(message: String?) : CwaClientError(429, message) + +class InternalServerErrorException(message: String?) : CwaServerError(500, message) +class NotImplementedException(message: String?) : CwaServerError(501, message) +class BadGatewayException(message: String?) : CwaServerError(502, message) +class ServiceUnavailableException(message: String?) : CwaServerError(503, message) +class GatewayTimeoutException(message: String?) : CwaServerError(504, message) +class HTTPVersionNotSupported(message: String?) : CwaServerError(505, message) +class NetworkAuthenticationRequiredException(message: String?) : CwaServerError(511, message) +class CwaUnknownHostException( + message: String? = null, + cause: Throwable? +) : CwaServerError(597, message, cause) + +class NetworkReadTimeoutException(message: String?) : CwaServerError(598, message) +class NetworkConnectTimeoutException( + message: String? = null, + cause: Throwable? = null +) : CwaServerError(599, message, cause) diff --git a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt index 1061abc7e164af4ff5ac41ec2e63776004ebcce3..40765f7fa89c1dbc9f350737c818cbf97900a35d 100644 --- a/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt +++ b/Corona-Warn-App/src/main/java/de/rki/coronawarnapp/http/HttpErrorParser.kt @@ -26,6 +26,7 @@ import de.rki.coronawarnapp.exception.http.UnauthorizedException import de.rki.coronawarnapp.exception.http.UnsupportedMediaTypeException import okhttp3.Interceptor import okhttp3.Response +import timber.log.Timber import java.net.SocketTimeoutException import java.net.UnknownHostException import javax.net.ssl.HttpsURLConnection @@ -34,43 +35,54 @@ class HttpErrorParser : Interceptor { override fun intercept(chain: Interceptor.Chain): Response { try { val response = chain.proceed(chain.request()) + + val message: String? = try { + if (response.isSuccessful) { + null + } else { + response.message + } + } catch (e: Exception) { + Timber.w("Failed to get http error message.") + null + } return when (val code = response.code) { HttpsURLConnection.HTTP_OK -> response HttpsURLConnection.HTTP_CREATED -> response HttpsURLConnection.HTTP_ACCEPTED -> response HttpsURLConnection.HTTP_NO_CONTENT -> response - HttpsURLConnection.HTTP_BAD_REQUEST -> throw BadRequestException() - HttpsURLConnection.HTTP_UNAUTHORIZED -> throw UnauthorizedException() - HttpsURLConnection.HTTP_FORBIDDEN -> throw ForbiddenException() - HttpsURLConnection.HTTP_NOT_FOUND -> throw NotFoundException() - HttpsURLConnection.HTTP_CONFLICT -> throw ConflictException() - HttpsURLConnection.HTTP_GONE -> throw GoneException() - HttpsURLConnection.HTTP_UNSUPPORTED_TYPE -> throw UnsupportedMediaTypeException() - 429 -> throw TooManyRequestsException() - HttpsURLConnection.HTTP_INTERNAL_ERROR -> throw InternalServerErrorException() - HttpsURLConnection.HTTP_NOT_IMPLEMENTED -> throw NotImplementedException() - HttpsURLConnection.HTTP_BAD_GATEWAY -> throw BadGatewayException() - HttpsURLConnection.HTTP_UNAVAILABLE -> throw ServiceUnavailableException() - HttpsURLConnection.HTTP_GATEWAY_TIMEOUT -> throw GatewayTimeoutException() - HttpsURLConnection.HTTP_VERSION -> throw HTTPVersionNotSupported() - 511 -> throw NetworkAuthenticationRequiredException() - 598 -> throw NetworkReadTimeoutException() - 599 -> throw NetworkConnectTimeoutException() + HttpsURLConnection.HTTP_BAD_REQUEST -> throw BadRequestException(message) + HttpsURLConnection.HTTP_UNAUTHORIZED -> throw UnauthorizedException(message) + HttpsURLConnection.HTTP_FORBIDDEN -> throw ForbiddenException(message) + HttpsURLConnection.HTTP_NOT_FOUND -> throw NotFoundException(message) + HttpsURLConnection.HTTP_CONFLICT -> throw ConflictException(message) + HttpsURLConnection.HTTP_GONE -> throw GoneException(message) + HttpsURLConnection.HTTP_UNSUPPORTED_TYPE -> throw UnsupportedMediaTypeException(message) + 429 -> throw TooManyRequestsException(message) + HttpsURLConnection.HTTP_INTERNAL_ERROR -> throw InternalServerErrorException(message) + HttpsURLConnection.HTTP_NOT_IMPLEMENTED -> throw NotImplementedException(message) + HttpsURLConnection.HTTP_BAD_GATEWAY -> throw BadGatewayException(message) + HttpsURLConnection.HTTP_UNAVAILABLE -> throw ServiceUnavailableException(message) + HttpsURLConnection.HTTP_GATEWAY_TIMEOUT -> throw GatewayTimeoutException(message) + HttpsURLConnection.HTTP_VERSION -> throw HTTPVersionNotSupported(message) + 511 -> throw NetworkAuthenticationRequiredException(message) + 598 -> throw NetworkReadTimeoutException(message) + 599 -> throw NetworkConnectTimeoutException(message) else -> { - if (code in 100..199) throw CwaInformationalNotSupportedError(code) + if (code in 100..199) throw CwaInformationalNotSupportedError(code, message) if (code in 200..299) throw CwaSuccessResponseWithCodeMismatchNotSupportedError( - code + code, message ) - if (code in 300..399) throw CwaRedirectNotSupportedError(code) - if (code in 400..499) throw CwaClientError(code) - if (code in 500..599) throw CwaServerError(code) - throw CwaWebException(code) + if (code in 300..399) throw CwaRedirectNotSupportedError(code, message) + if (code in 400..499) throw CwaClientError(code, message) + if (code in 500..599) throw CwaServerError(code, message) + throw CwaWebException(code, message) } } } catch (err: SocketTimeoutException) { - throw NetworkConnectTimeoutException() + throw NetworkConnectTimeoutException(cause = err) } catch (err: UnknownHostException) { - throw CwaUnknownHostException() + throw CwaUnknownHostException(cause = err) } } }