优雅实现Ktor Client请求异常处理
代码
参考官方文档简单处理特殊 Status Code 响应错误,最简单的方式则是打印日志,当然可以根据自己的情况来包装。
private suspend fun ResponseException.debugLogging() {
when (this) {
is RedirectResponseException -> {
// Status codes 3XX
val errorString = response.body<String>()
println("===== $errorString")
}
is ClientRequestException -> {
// status codes 4XX
println("===== status codes 4XX")
}
is ServerResponseException -> {
// status codes 5XX
println("===== status codes 5XX")
}
}
}
整合模板代码实现如下
internal suspend inline fun <reified T> HttpClient.doGetWithCatch(
urlString: String,
isThrows: Boolean = false,
block: HttpRequestBuilder.() -> Unit = {}
): T? {
return try {
get(urlString, block).body<T>()
} catch (exception: ResponseException) {
exception.debugLogging()
if (isThrows) throw exception else null
} catch (ioException: IOException) {
if (isThrows) throw ioException else null
}
}
上面代码是适配get请求的,post一样,就不拷贝出来了。 加了一个参数isThrows
作为是否将异常往上抛让调用者进行处理的标识。
使用
override suspend fun getCoinsMarkets(
currency: String,
page: Int,
numCoinsPerPage: Int,
order: String,
includeSparkline7dData: Boolean,
priceChangePercentageIntervals: String,
coinIds: String?
): List<CoinGeckoMarketsDto> {
return httpClient.doGetWithCatch<List<CoinGeckoMarketsDto>>("coins/markets") {
parameter("vs_currency", currency)
parameter("page", page)
parameter("per_page", numCoinsPerPage)
parameter("order", order)
parameter("sparkline", includeSparkline7dData)
parameter("price_change_percentage", priceChangePercentageIntervals)
parameter("ids", coinIds)
} ?: emptyList()
}
是不是看起来舒服多了?特别是在接口需要实现的方法多的时候,修改之后特有满足感