含cause参数的自定义异常无法被Crashlytics recordException记录求助
为什么带Cause参数的自定义异常无法被Firebase Crashlytics记录?
问题场景
在Kotlin的Result.onFailure回调中向Firebase Crashlytics记录异常时,以下两种方式可以正常上报:
- 直接传入原始Throwable对象:
FirebaseCrashlytics.getInstance().recordException(it) - 使用带message参数的自定义异常:
自定义异常定义:FirebaseCrashlytics.getInstance().recordException(MyCustomException("test message"))class MyCustomException(message: String) : Exception(message)
但使用仅带cause参数的自定义异常时,异常无法被Crashlytics记录:
FirebaseCrashlytics.getInstance().recordException(MyCustomException(it))
对应的自定义异常:
class MyCustomException(t: Throwable) : Exception(t)
原因分析
Firebase Crashlytics的异常上报逻辑依赖于异常的非空message字段和完整的栈轨迹信息来识别、解析并记录异常。当你通过Exception(t)构造自定义异常时,父类Exception的构造器会将message设置为cause.toString(),但存在两个关键问题:
- 如果原始Throwable(即
it)本身没有有效message,生成的自定义异常message可能为空或仅包含类名,部分Crashlytics SDK版本会过滤这类“信息不足”的异常; - 部分旧版本的Crashlytics SDK对仅通过cause构造的自定义异常存在兼容性问题,会导致异常被静默丢弃,无法完成上报。
解决方案
通过同时指定message和cause来构造自定义异常,确保Crashlytics能识别到完整的异常信息:
- 调整自定义异常的构造器,同时支持message和cause:
class MyCustomException(message: String, cause: Throwable?) : Exception(message, cause)
使用时传入明确的错误描述和原始异常:
FirebaseCrashlytics.getInstance().recordException(MyCustomException("操作失败", it))
- 如果想保留仅传cause的构造方式,手动填充message:
class MyCustomException(t: Throwable) : Exception( message = "Wrapped exception: ${t.message ?: t.javaClass.simpleName}", cause = t )
这样即使原始异常没有message,自定义异常也会包含明确的描述,确保Crashlytics能正常上报。
内容的提问来源于stack exchange,提问作者aaronmarino
相关产品推荐
相关产品推荐

