dorche
08/05/2026, 11:59 AMdorche
08/05/2026, 12:00 PMCrashlyticsKotlin.sendHandledException(IllegalStateException("Expected one of X, Y, Z but got $badField"))dorche
08/05/2026, 12:03 PMdorche
08/05/2026, 12:07 PMwellingtoncosta
08/10/2026, 6:17 PMFIRStackFrameWithAddress(it.convert()) is actually about the grouping input.
Firebase's Apple docs say: "Unlike fatal crashes, which are grouped via stack trace analysis, logged errors are grouped by domain and code." That applies to recordError(NSError), but CrashKiOS uses the record(exceptionModel:) (see FIRCrashlyticsRecordExceptionModel), which carries a real stack trace, pretty similar to Android with recordException(throwable).
By the way, there's a trap when creating a helper function to report an exception so the top frame will be always the helper function name:
// BAD: every caller collapses to one issue and the top frame is always `reportBadField`
fun reportBadField(msg: String) = CrashlyticsKotlin.sendHandledException(IllegalStateException(msg))
// GOOD: throwable constructed at the call site → distinct top frame per site
CrashlyticsKotlin.sendHandledException(IllegalStateException("Expected one of X, Y, Z but got $badField"))
Another good practice is to create custom exceptions (I know the question was not about that but worth mention) for a readable dashboard title:
class UnexpectedApiValueException(message: String) : IllegalStateException(message)
So, using the CrashlyticsKotlin.sendHandledException should be fine.dorche
08/11/2026, 2:50 PMco.touchlab.kermit.Logger.e(IllegalStateException(message), "message")
which then on Production builds can log to Crashlytics, via a custom Kermit LogWriter
class CrashlyticsLogWriter : LogWriter() {
override fun log(
severity: Severity,
message: String,
tag: String,
throwable: Throwable?
) {
throwable?.let {
CrashlyticsKotlin.sendHandledException(throwable)
}
}
}
LogWriter's log function is not inline I think so I am unsure if that will quite work 🤔