首页 > 解决方案 > Kotlin - 自定义异常作为数据类?

问题描述

在 Kotlin 中,创建自定义异常非常容易。下面是一个接受code作为参数的示例:

class PortraitRequestFailedException(val code: Int) : RuntimeException()

code包含从服务器返回的 http 响应错误代码。问题是,当记录器一般报告该异常时,例如Timber.e(exception, "Error loading portrait cover photo url")code输出中会丢失:

2020-02-14 13:50:59.886 15942-16232 E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
    com.example.data.PortraitManager$PortraitRequestFailedException
        at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)

当然,我可以添加一个when exception is PortraitRequestFailedException子句并专门处理该特定错误,但我不希望这样(尤其是 Kotlin 中的所有异常都未检查,我可能不知道期望什么类型)。

我找到了一种将代码RuntimeException作为message参数传递给 a 的简单方法:

class PortraitRequestFailedException(val code: Int) : RuntimeException(code.toString())

2020-02-14 13:40:32.878 430-857 E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
    com.example.data.PortraitManager$PortraitRequestFailedException: 403
        at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)

但是这种方法对我来说看起来有点过于冗长(我需要code在父类构造函数中引用),它只会 print PortraitRequestFailedException: 403,而不是告诉 403 指的是什么(想象这里有多个参数)。

所以我想出了将自定义异常定义为数据类的想法:

data class PortraitRequestFailedException(val code: Int) : RuntimeException()

由于 Kotlin 中的数据类有一个以 . 形式自动生成的toString()方法PortraitRequestFailedException(code=403),因此这种表示法具有我想要的所有优点,而无需添加冗长或样板代码。日志如下:

E/PortraitManager$watchCoverPhotoUrl: Error loading portrait cover photo url
    PortraitRequestFailedException(code=403)
        at com.example.data.PortraitManager$loadCoverPhotoUrl$1.call(PortraitManager.kt:139)

您认为这种方法有什么缺点吗?将异常作为数据类处理有什么危险吗?

标签: exceptionkotlin

解决方案


我稍微倾向于手动覆盖toString()自己,因为这是您唯一需要的data class. 但总的来说,它确实有效,并且没有明显的缺点。


推荐阅读