解析 ktor HTTPClient 中的错误正文

Kap*_*l G 4 kotlin ktor kotlin-multiplatform ktor-client

我有一个 api,它在发送错误请求时返回带有正确错误信息的错误正文。例如,我得到状态代码 400 和以下正文 -

{
  "errorCode": 1011,
  "errorMessage": "Unable to get Child information"
}
Run Code Online (Sandbox Code Playgroud)

现在,当我为此在多平台模块中编写 ktor 客户端时,我会在响应验证器中捕获它,例如 -

 HttpResponseValidator {
            validateResponse {
                val statusCode = it.status.value
                when (statusCode) {
                    in 300..399 -> print(it.content.toString())
                    in 400..499 -> {
                        print(it.content.toString())
                        throw ClientRequestException(it)
                    }
                    in 500..599 -> print(it.content.toString())
                }
            }
            handleResponseException {
                print(it.message)
            }
        }
Run Code Online (Sandbox Code Playgroud)

我在这里的查询是我不能够访问响应误差身体任一validateResponsehandleResponseException。有没有办法可以捕获并解析它以获取服务器发送的实际错误?

小智 7

您可以声明一个数据类 Error 来表示您期望的错误响应。

import kotlinx.serialization.Serializable

@Serializable
data class Error(
    val errorCode: Int,   //if by errorCode you mean the http status code is not really necessary to include here as you already know it from the validateResponse
    val errorMessage: String
)
Run Code Online (Sandbox Code Playgroud)

您可以有一个暂停的乐趣来解析响应并将其作为 Error 数据类的一个实例

 suspend fun getError(responseContent: ByteReadChannel): Error {
    responseContent.readUTF8Line()?.let {
        return Json(JsonConfiguration.Stable).parse(Error.serializer(), it)
    }
    throw IllegalArgumentException("not a parsable error")
}
Run Code Online (Sandbox Code Playgroud)

然后在 handleResponseException 里面

handleResponseException { cause -> 
            val error = when (cause) {
                is ClientRequestException -> exceptionHandler.getError(cause.response.content)
// other cases here 

                else -> // throw Exception() do whatever you need 
            }
//resume with the error 
        }
Run Code Online (Sandbox Code Playgroud)

例如,您可以根据抛出异常并在代码中的其他地方捕获它的错误来实现一些逻辑

when (error.errorCode) {
        1-> throw MyCustomException(error.errorMessage)
        else -> throw Exception(error.errorMessage)
    }
Run Code Online (Sandbox Code Playgroud)

我希望它有帮助

  • 只是为了分享,截至今天,我设法只使用“cause.response.readText()”来获取我的 api 错误文本。 (2认同)