Skip to content

Commit

Permalink
Made DefaultErrorHandler extensible
Browse files Browse the repository at this point in the history
  • Loading branch information
bastianeicher committed Jul 7, 2024
1 parent 735f7ad commit 1a9c39b
Showing 1 changed file with 22 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,35 @@ import kotlinx.serialization.*
import kotlinx.serialization.json.Json
import net.typedrest.http.HttpStatusCode
import okhttp3.Response
import java.io.IOException
import okhttp3.ResponseBody

/**
* Handles errors in HTTP responses by mapping status codes to common exception types.
*/
class DefaultErrorHandler : ErrorHandler {
open class DefaultErrorHandler : ErrorHandler {
@Throws(HttpException::class)
override fun handle(response: Response) {
if (response.isSuccessful) return

val body = response.body?.string()
val message = extractJsonMessage(response, body)
val message = response.body?.let(::extractJsonMessage)
?: "${response.request.url} responded with ${response.code} ${response.message}"

throw mapException(HttpStatusCode.parse(response.code) ?: HttpStatusCode.InternalServerError, message, response)
}

private fun extractJsonMessage(response: Response, body: String?): String? {
if (body.isNullOrEmpty()) return null

val mediaType = response.body?.contentType()?.toString()
if (mediaType != "application/json" && (mediaType == null || !mediaType.endsWith("+json"))) return null
/**
* Tries to extract an error message from the response body.
*
* @param body The response body.
*/
protected open fun extractJsonMessage(body: ResponseBody): String? {
val mediaType = body.contentType()?.toString()
if (mediaType == null || (mediaType != "application/json" && !mediaType.endsWith("+json"))) {
return null
}

return try {
val decoded = Json.decodeFromString<JsonErrorResponse>(body)
val decoded = Json.decodeFromString<JsonErrorResponse>(body.string())
return decoded.message ?: decoded.details
} catch (e: SerializationException) {
null
Expand All @@ -38,7 +42,14 @@ class DefaultErrorHandler : ErrorHandler {
@Serializable
private class JsonErrorResponse(val message: String?, val details: String? = null)

private fun mapException(status: HttpStatusCode, message: String, response: Response?) =
/**
* Maps the HTTP status code to an exception.
*
* @param status The status code.
* @param message An error message to include in the exception.
* @param response The HTTP response to include in the exception.
*/
protected open fun mapException(status: HttpStatusCode, message: String, response: Response?) =
when (status) {
HttpStatusCode.BadRequest -> BadRequestException(message, status, response)
HttpStatusCode.Unauthorized -> AuthenticationException(message, status, response)
Expand Down

0 comments on commit 1a9c39b

Please sign in to comment.