Kotlin中API响应的错误与异常处理优化方案咨询
优化API错误与异常处理方案
针对你的需求,现有实现的核心问题是APIResponse的OnFailure只能接受ErrorResponseDto,无法直接传递异常,导致你需要手动将异常转成ErrorResponseDto,显得不够优雅。以下是两种更优的处理方案:
方案一:扩展APIResponse密封类,区分API错误与异常
将APIResponse改为密封类,新增专门处理异常的子类,让调用方可以明确区分「API返回的错误响应」和「客户端抛出的异常」(如网络错误、序列化失败等):
修改APIResponse定义
sealed class APIResponse<out T> { // 接口返回成功数据 data class OnSuccess<T>(val data: T) : APIResponse<T>() // 接口返回错误状态码及错误响应体 data class OnApiFailure(val error: ErrorResponseDto) : APIResponse<Nothing>() // 客户端执行过程中抛出异常 data class OnException(val exception: Exception) : APIResponse<Nothing>() }
修改loginUser实现
override suspend fun loginUser(loginRequestModel: LoginRequestModel): APIResponse<LoginResponseDto> { return try { val response = httpClient .post("https://endpoint") { contentType(ContentType.Application.Json) setBody(LoginRequestDto(/* body data */)) } when (response.status.value) { 200 -> APIResponse.OnSuccess(response.body()) else -> APIResponse.OnApiFailure(response.body()) } } catch (exception: Exception) { if (exception is CancellationException) { Timber.e(exception) throw exception // 协程取消异常需重新抛出,不纳入业务错误处理 } Timber.e(exception) APIResponse.OnException(exception) } }
调用方处理示例
when (val response = loginUser(request)) { is APIResponse.OnSuccess -> // 处理成功数据 is APIResponse.OnApiFailure -> // 处理API返回的错误响应 is APIResponse.OnException -> // 处理客户端异常(如网络错误) }
这个方案的优势是边界清晰,调用方可以针对不同错误类型做精细化处理。
方案二:统一错误模型,优雅转换异常为ErrorResponseDto
如果希望保持现有APIResponse的结构不变,只需优化异常转ErrorResponseDto的代码,可通过扩展函数封装转换逻辑,避免重复代码:
添加异常转ErrorResponseDto的扩展函数
fun Exception.toErrorResponseDto(): ErrorResponseDto { return ErrorResponseDto( errors = listOf( ErrorDto( code = localizedMessage ?: "CLIENT_EXCEPTION", detail = message ?: "未知客户端错误" ) ) ) }
修改loginUser中的catch块
catch (exception: Exception) { if (exception is CancellationException) { Timber.e(exception) throw exception } Timber.e(exception) APIResponse.OnFailure(exception.toErrorResponseDto()) }
这个方案的优势是保持原有接口结构不变,同时让异常转换逻辑更整洁、可复用。
关键注意点
- 保留
CancellationException的重新抛出是正确的,因为协程取消属于流程控制,不应被包装为业务错误。 - 若选择方案一,建议在
OnException中额外记录异常日志,便于排查问题。
内容的提问来源于stack exchange,提问作者ant2009
相关产品推荐
相关产品推荐

