Crashlytics iOS - log caught exception
Mike from Crashlytics and Fabric here.
You can now capture logged NSErrors in your iOS, tvOS, or OS X app. You want to use:
[CrashlyticsKit recordError:error];
or
Crashlytics.sharedInstance().recordError(error)
This will let you capture a fair number of logged NSErrors per user session. These are only sent on app relaunch. Logged errors errors are grouped by the error domain and code. This means error issues can span many different call sites.
See Documentation
Flutter Crashlytics log caught exception
Short answer, yes.
Crashlytics.instance.recordError()
is the equivalent of Crashlytics.logException()
If you dig into the Flutter firebase_crashlytics source code, you can actually see what Android APIs are involved.
Flutter’s recordError() invokes the method Crashlytics#onError in the Android library.
And tracing Crashlytics#onError, you’ll see that it goes to Crashlytics.logException(exception);
Additional note, you’ll also notice why Crashlytics.instance.log()
”will only add logs to the next crash report”. These logs are added to a ListQueue<String> _logs
which is then packaged into the next call of recordError()
A snippet of Flutter’s invocation of Crashlytics.logException():
_recordError(...) {
...
final String result = await channel
.invokeMethod<String>('Crashlytics#onError', <String, dynamic>{
'exception': "${exception.toString()}",
'context': '$context',
'information': _information,
'stackTraceElements': stackTraceElements,
'logs': _logs.toList(),
'keys': _prepareKeys(),
});
}
And some reference notes for Crashlytics.logException():
To reduce your users’ network traffic, Crashlytics batches logged
exceptions together and sends them the next time the app launches.For any individual app session, only the most recent 8 logged
exceptions are stored.
Does firebase_crashlytics work when using try / catch in flutter?
I think solution are
Crashlytics.instance.log
for log Single message, string.Crashlytics.instance.recordError
for log message error with stackTrace.Crashlytics.instance.recordFlutterError
for log message is generated by flutter framework
How to find the exact exception that's being occured or the root cause from the crash logs ios
Unrelated, but in Swift, there is no need for ;
at the end of the lines.
Let's read the crash log:
2 watch Extension 0x04488074 closure #1 in OtpView.fetchProfile() + 1232 (OtpView.swift:203)
3 watch Extension 0x0443c47c specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) + 1120 (Inteceptor.swift:0)
4 watch Extension 0x0443dc80 partial apply for specialized closure #1 in closure #1 in useInteceptor(urlString:method:requestBody:completionHandler:) + 72 (<compiler-generated>:0)
That's the interesting part (the top ones with names of methods), you read them from the bottom.
So in Interceptor.swift
, method useInteceptor(urlString:method:requestBody:completionHandler:)
is called at some point.
In this one, there is a closure
(or multiple ones), but at least, in the first one (closure #1
), which is completionHandler
, that you call in fetchProfile
of OptView
class in OptView.swift
file.
And there, in line 203, it's the line causing the crash.
Let's analyze the culprit:
let profile = try! JSONDecoder().decode(ProfileResponse.self, from: data)
Here, the possible crash is because of try!
.
Why did you use try!
instead of writing a do
/try
/catch
? Do you know why you used a force unwrap !
here? What it means?
It means that if an error is thrown, just make the app crash.
So if there is a crash, it's expected behavior, since you explicitly wrote "crash here if there is thrown error".
So, now, why would decode(_:from:)
crash?
I don't know what's ProfileResponse
, but that method could throw an error because you didn't specify to it that a value in the JSON can be nul, a value in the JSON can be omitted, because there is another issue with the received JSON, or JSON is invalid.
Or, because your API is giving a bad value. It's sometimes the cases when API encounters an error, they could responds: {"error": "some reason why it failed"}
. It's a valid JSON, but I don't think that ProfileResponse
expect to be like that.
Now, as why it giving bad response, it's up to your Web API, check the doc, check the API developers for possible responses: Did you use bad parameters, are you falling into the one case not handled by back-end?
So when you wrote that line with the try!
, you decided to tell: "Don't worry about the response, if there is a response, I'm sure of it that it can be decoded into a ProfileResponse
object. Trust me, I know what I'm doing, I guarantee it will be always valid, and if that's not the case, just crash, that would prove me wrong, but rest assured, I'm sure of myself". Yes, that what meant try!
.
If you don't want to crash, don't use !
, and write a property do
/try
/catch
.
do {
let profile = try JSONDecoder().decode(ProfileResponse.self, from: data)
if let ratePlanDetails = profile.response?.detail {
self.navigateToNext.toggle()
}
} catch {
print("Oops, there was an error while decoding ProfileResponse: \(error)")
print("And the API response was: \(String(data: data, encoding: .utf8) ?? "unknown data")")
}
Now, as to why you have an invalid response, that's up to your debugging: trying to reproduce it, with specific params, specific case, etc.). We can't guess what's wrong, we can't guess what's returning the API.
Once you know what's the real response sent back by your API, and don't know how to handle it, you can ask a new question on SO and we might help you, but at this point, we can't do anything more about your issue.
Related Topics
How to Calculate the Age Based on Nsdate
Upload Multiple Images in Swift Using Alamofire
Opengl Es 2.0 Object Picking on iOS
Nsarray with Nspredicate Using Not In
How to Set a Default Value of a Uipickerview
Differencebetween a Development Provisioning Profile and an Ad Hoc Provisioning Profile
Accessing iOS Safari Web Inspector from Windows MAChine
Get iOS Itunes App Store Id of an App Itself
How to Check If a Uialertcontroller Is Already Presenting
Swiftui: Unwanted Split View on iPad
How to Disable Caching from Nsurlsessiontask
How to Push Two View Controllers But Animate Transition Only for the Second One
Pod Error in Xcode "Id: Framework Not Found Pods"
Spacing Between Uitableviewcells
Cross Directional Uiscrollviews - How to Modify the Scrolling Behaviour