如何在 Kotlin 的公共 class 处处理不同函数的捕获异常?
How can I handle catch exception for different functions at a common class in Kotlin?
这是我的 RemoteDataSource class,我将在其中编写许多 api 调用,如下所示:
suspend fun getReviewData1() = getResult {
try {
apiService.getReviewData(getCustomerId())
} catch (e: Exception) {
handleException(e)
}
}
suspend fun getReviewData2() = getResult {
try {
apiService.getReviewData(getCustomerId())
} catch (e: Exception) {
handleException(e)
}
}
现在,您可以看到,对于每个乐趣,我都需要将我的代码包装在 try/catch 块中。一切正常,我也能捕捉到异常,但为什么要为每个函数写这么多 try/catch 呢?相反,我需要做一个常见的 class,这样我就可以像这样简单地调用我的函数。
suspend fun getReviewData() = getResult {
apiService.getReviewData(getCustomerId())
}
如果你想做任何改变,你可以写一个答案并建议我,例如 getResult()
getResult() 在另一个基地 class:
protected suspend fun <T> getResult(call: suspend () -> Response<T>?): Resource<T> {
try {
val response = call()
if (response?.isSuccessful == true) {
val body = response.body()
if (body != null) return Resource.success(body, response.message(), response.code())
}
return error((response?.message() ?: context.getString(R.string.unable_to_reach_server)),
(response?.code() ?: AppConstants.INetworkValues.DEFAULT_ERROR_CODE))
} catch (e: Exception) {
return error(e.message ?: e.toString(), (call()?.code() ?: AppConstants.INetworkValues.DEFAULT_ERROR_CODE))
}
}
private fun <T> error(message: String, code: Int): Resource<T> {
LogUtils.d(message)
return Resource.error(null, message, code)
}
handleException()
fun handleException(e: Exception): Response<Any> {
if (e is NoConnectivityException) {
return Response.error(AppConstants.INetworkValues.INTERNET_ERROR_CODE, getDummyResponseBody())
} else {
return Response.error(AppConstants.INetworkValues.DEFAULT_ERROR_CODE, getDummyResponseBody())
}
}
我试过这个答案,但它没有发生:
请帮忙。
您的 getResult
函数在 catch 块中有错误。如果第一次调用 call()
抛出异常,您将再次调用 call()
。我认为再次调用它没有意义,因为它可能会再次抛出并且您将无法 return 您的 Resource.error
.
如果你解决了这个问题,你就不需要在你的其他函数中使用 try/catch,因为 call
将被安全地包装在 try/catch
中并将任何错误打包到一个Resource.error
.
修复它:因为您已经在 try 块中处理了 response?.code
,所以没有理由在 catch 块中重复获取 call()?.code
。您可以将其简化为
return error(e.message ?: e.toString(), AppConstants.INetworkValues.DEFAULT_ERROR_CODE)
这是我的 RemoteDataSource class,我将在其中编写许多 api 调用,如下所示:
suspend fun getReviewData1() = getResult {
try {
apiService.getReviewData(getCustomerId())
} catch (e: Exception) {
handleException(e)
}
}
suspend fun getReviewData2() = getResult {
try {
apiService.getReviewData(getCustomerId())
} catch (e: Exception) {
handleException(e)
}
}
现在,您可以看到,对于每个乐趣,我都需要将我的代码包装在 try/catch 块中。一切正常,我也能捕捉到异常,但为什么要为每个函数写这么多 try/catch 呢?相反,我需要做一个常见的 class,这样我就可以像这样简单地调用我的函数。
suspend fun getReviewData() = getResult {
apiService.getReviewData(getCustomerId())
}
如果你想做任何改变,你可以写一个答案并建议我,例如 getResult()
getResult() 在另一个基地 class:
protected suspend fun <T> getResult(call: suspend () -> Response<T>?): Resource<T> {
try {
val response = call()
if (response?.isSuccessful == true) {
val body = response.body()
if (body != null) return Resource.success(body, response.message(), response.code())
}
return error((response?.message() ?: context.getString(R.string.unable_to_reach_server)),
(response?.code() ?: AppConstants.INetworkValues.DEFAULT_ERROR_CODE))
} catch (e: Exception) {
return error(e.message ?: e.toString(), (call()?.code() ?: AppConstants.INetworkValues.DEFAULT_ERROR_CODE))
}
}
private fun <T> error(message: String, code: Int): Resource<T> {
LogUtils.d(message)
return Resource.error(null, message, code)
}
handleException()
fun handleException(e: Exception): Response<Any> {
if (e is NoConnectivityException) {
return Response.error(AppConstants.INetworkValues.INTERNET_ERROR_CODE, getDummyResponseBody())
} else {
return Response.error(AppConstants.INetworkValues.DEFAULT_ERROR_CODE, getDummyResponseBody())
}
}
我试过这个答案,但它没有发生:
请帮忙。
您的 getResult
函数在 catch 块中有错误。如果第一次调用 call()
抛出异常,您将再次调用 call()
。我认为再次调用它没有意义,因为它可能会再次抛出并且您将无法 return 您的 Resource.error
.
如果你解决了这个问题,你就不需要在你的其他函数中使用 try/catch,因为 call
将被安全地包装在 try/catch
中并将任何错误打包到一个Resource.error
.
修复它:因为您已经在 try 块中处理了 response?.code
,所以没有理由在 catch 块中重复获取 call()?.code
。您可以将其简化为
return error(e.message ?: e.toString(), AppConstants.INetworkValues.DEFAULT_ERROR_CODE)