We all know that mobile is compact platform where we have to look lots of things while building an application. It could be anything e.g. Memory
Performance
Resolutions
Architecture
Implementation
etc. We never know when and what causes app crash a big ISSUE while playing with the app, It could happen anytime
e.g. App Launch, Load Screen, API Call, Binding Data, Loading Images etc.
And trust me sometime its really hard to find where and what cause an issue in app. I saw many post on forums, tech community and groups which is related to the same issue, where peoples usually asking questions as:
- App Crashing at launching.
- App Crash at Splash Screen loading.
- App Crash while Image showing.
- App Crashing while binding data from api.
How to identify issue and where it causes?
Purpose: Our purpose here to grab an exception's stack trace data that help us to identify what exactly causes the issue whether in Release Mode
or Debug Mode
. We will be able to understand the issue and the reason that causes it. We will store this data in a text
file that will be store in device storage.
Solution: Alternatively you can make your own insight grabber that will give you you app insight and clue if something went wrong while testing the app. Its will be your, you can tweak like you want. let's dive to try{}
and catch{}
globally.
Create a Helper Class
file that has a method to generate a Text file for exception data.
public static class ExceptionFileWriter
{
#region Property File Path
static string FilePath
{
get
{
string path = string.Empty;
var _fileName = "Fatal.txt";
#if __IOS__
string documentsPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); // Documents folder C:\ddddd
string libraryPath = Path.Combine(documentsPath, "..", "Library"); // Library folder C:\dddd\...\library
path = Path.Combine(libraryPath, _fileName); //c:\ddddd\...\library\NBCCSeva.db3
#else
#if __ANDROID__
string dir = Path.Combine(Android.OS.Environment.ExternalStorageDirectory.ToString(), "Exception");
if (Directory.Exists(dir))
return Path.Combine(dir, _fileName);
path= Path.Combine(Directory.CreateDirectory(dir).FullName, _fileName);
#endif
#endif
return path;
}
}
#endregion
#region ToLog Exception
public static void ToLogUnhandledException(this Exception exception)
{
try
{
var errorMessage = String.Format("Time: {0}\r\nError: Unhandled Exception\r\n{1}\n\n", DateTime.Now, string.IsNullOrEmpty(exception.StackTrace) ? exception.ToString() : exception.StackTrace);
File.WriteAllText(FilePath, errorMessage);
}
catch (Exception ex)
{
// just suppress any error logging exceptions
}
}
#endregion
}
Time to implement code: Subscribe following events inside your app's Application
file or Splash Activity
. I'm using Application in this case.
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
[Application]
public class ExceptionHandlingApp : Application
{
#region Constructor
public ExceptionHandlingApp(IntPtr javaReference, JniHandleOwnership transfer)
: base(javaReference, transfer)
{
}
#endregion
#region OnCreate
public override void OnCreate()
{
base.OnCreate();
AppDomain.CurrentDomain.UnhandledException += CurrentDomainOnUnhandledException;
TaskScheduler.UnobservedTaskException += TaskSchedulerOnUnobservedTaskException;
}
#endregion
#region Task Schedular Exception
private static void TaskSchedulerOnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs unobservedTaskExceptionEventArgs)
{
var newExc = new Exception("TaskSchedulerOnUnobservedTaskException", unobservedTaskExceptionEventArgs.Exception);
newExc.ToLogUnhandledException();
}
#endregion
#region Current Domain Exception
private static void CurrentDomainOnUnhandledException(object sender, UnhandledExceptionEventArgs unhandledExceptionEventArgs)
{
var newExc = new Exception("CurrentDomainOnUnhandledException", unhandledExceptionEventArgs.ExceptionObject as Exception);
newExc.ToLogUnhandledException();
}
#endregion
}
Note: You can find exceptions record file in Device Storage | File Manager > Exception Folder > fatal.txt
Cheers!!
Result Video
Full Article
Beside of doing it on your own you can also use Xamarin.Insights as it is free to use for Xamarin users and has got implementations for all platforms.
You receive usage reports, crash reports etc. online without the need for the user to send you a log file manually.
The only thing you need to do to receive crash reports is to initialize Xamarin.Insights on startup of your app:
Insights.HasPendingCrashReport += (sender, isStartupCrash) =>
{
if (isStartupCrash) {
Insights.PurgePendingCrashReports().Wait();
}
};
Insights.Initialize("Your API Key");