public class XamAppExceptionHandler : BitExceptionHandler { public override void OnExceptionReceived(Exception exp, IDictionary<string, string> properties = null) { #if DEBUG System.Diagnostics.Debugger.Break(); #endif base.OnExceptionReceived(exp, properties); } }
BitExceptionHandler.Current = new XamAppExceptionHandler();
حال برای لاگ کردن این خطاها، میتوانید از Microsoft's AppCenter استفاده کنید. استفاده از امکانات App Center رایگان بوده و برای استفادهی در ایران محدودیتی ندارد. ابتدا در سایت مربوطه ثبت نام کنید و سپس سه بار Add New app را بزنید و به نامهای XamApp_Windows، XamApp_iOS و XamApp_Android سه برنامه را بسازید و برای Android و iOS گزینهی Xamarin را انتخاب و برای ویندوز نیز UWP را انتخاب کنید.
سپس پکیجهای Microsoft.AppCenter.Crashes و Microsoft.AppCenter.Analytics را بر روی XamApp نصب نموده و کد زیر را در سه فایل AppDelegate.cs/MainActivity.cs/App.xaml.cs برای iOS/Android/Windows کپی کنید:
AppCenter.Start("copy-your-guid-key-for-iOS-Android-Windows-here", typeof(Crashes), typeof(Analytics));
برای هر یک از برنامههای Android/iOS/Windows یک Guid متفاوت دارید که در قسمت Getting Started در سایت App Center میتوانید آنها را مشاهده کنید. هر بار که این کد را کپی میکنید، مقدار Guid درست را بگذارید.
برای گزارش کردن خطاهای برنامه، کافی است کد زیر را به XamAppExceptionHandler.cs که در ابتدای این قسمت در موردش صحبت کرده بودیم اضافه کنید:
Crashes.TrackError(exp, properties);
حال اگر برنامه را اجرا و شروع به تست کنید و یا آن را در اختیار تسترها و مشتریها بگذارید، نه تنها گزارش تمامی خطاها و کرشها را خواهید داشت که حتی آمار استفاده کنندههای برنامه (شامل کشور و مشخصات دستگاه و ...) را نیز خواهید داشت.
حال در یک کد ده خطی، اگر در خط پنجم خطایی رخ دهد، اگر چه باعث بسته شدن برنامه نمیشود و لاگ نیز میشود، ولی در مواقعی خیلی خاص، شاید بخواهید در صورت رخ دادن خطا، چند خط کد بعدی کماکان اجرا شوند. در این حالت شما Try/Catch مینویسید که برای عبور کردن از خطا از آن استفاده کردهاید. در این صورت، ترجیحا آن را به شکل زیر بنویسید:
// code 1... try { // code 2... } catch (Exception ex) { BitExceptionHandler.Current.OnExceptionReceived(ex, new Dictionary<string, string> { { "SomeData", "2" } }); } // code 3...
در این کد مثال، فرض کنیم که برخی اوقات در code 2 خطایی رخ میدهد که برای ما مهم نیست و میخواهیم حتی در صورت رخ دادن خطا، code 3 اجرا شود. توصیه میکنیم در این موارد که در برنامه خیلی هم نباید متداول باشد، لااقل خطا را با کمک کد BitExceptionHandler.Current.OnExceptionReceived لاگ کنید و همچنین با داشتن یک Dictionary میتوانید حتی دیتای بیشتری را نیز به AppCenter فرستاده و در پرتال مربوطه مشاهده کنید.
به صورت کلی بهتر است از این نوع Try/Catchها پرهیز کنید و حتی اگر جایی Catch ای نوشتید، در نهایت دوباره خطا را throw کنید.
try { // some codes... } catch { // Do something related to exception... // for example, show some alerts to the user. throw; // You don't need to call BitExceptionHandler.Current.OnExceptionReceived... }
در مثال فوق، قصد داریم وقتی خطایی رخ داد، پیامی را به کاربر اطلاع دهیم. در این صورت، پس از نمایش پیام مربوطه، مجددا خطا را throw کنید. در این صورت، نیازی به فراخوانی BitExceptionHandler.Current.OnExceptionReceieved نیز نیست.
البته AppCenter در زمینه پابلیش کردن برنامه و همچنین Push Notification و ... نیز دارای امکاناتی هست که به موضوع این قسمت ارتباطی ندارند.