טיפול נכון בשגיאות הוא אחד הדברים המאתגרים בפיתוח אפליקציות, לדעתי אחד הדברים השגויים לעשות זה לכתוב בכל קטע קוד try, catch בלי לעשות כלום בקטע ה - catch רק כדי לבלום את התרסקות האפליקצייה.
הסיבה שהגישה הזו לא נכונה לדעתי, היא ש"טיפול" מסוג זה (כלומר לא לטפל רק להתעלם) יגרום בהכרח להתרסקות האפליקצייה במקום אחר מכיוון שאם קוד מסויים התרסק ולא עשה את העבודה כמו שצריך סביר להניח שקוד אחר המבוסס על הקוד שהתרסק לא יעבוד כמו שצריך, ובסוף התהליך כשנתרסק לא נדע את הסיבה האמיתית להתרסקות האפליקציה, (אם יצא לכם לדבג קוד שבכל מתודה יש בלוק try catch שלא עושה כלום, אתם כנראה מזדהים עם הכתיבה)
למעשה במידה והתרחשה שגיאה - ואני לא יודע כיצד לטפל בה אני מעוניין שהאפליקצייה תסגר (בצורה נעימה) כדי שאדע מה הייתה השגיאה.
הדרך הנכונה לטפל בשגיאות היא כך:
במידה ויודעים כיצד לטפל בה (למשל קבלת שם קובץ מהמשתמש) - לעטוף אותה בבלוק טיפול בשגיאות (לנסות לקבל שם קובץ חדש מהמשתמש),
במידה ורוצים להתעלם מהשגיאה (קורה לפעמים) לכתוב בלוק טיפול בשגיאות (ולכתוב ללוג את פרטי השגיאה),
בשאר המקרים יש לכתוב ללוג את הפרטים ולהציג הודעה מתאימה למשתמש ולפעמים אפילו לסגור את האפליקציה בצורה נכונה (לשמור מידע וכו').
כדי לחסוך את הצורך של כתיבת בלוק טיפול בשגיאות בכל מקום באפליקציה יש מקום מרכזי בו אפשר לכתוב קוד כללי של טיפול בשגיאות.
באפליקציות web יש את application_error ב - global.asax,
קוד מינימלי יהיה בסגנון הבא:
protected void Application_Error(object sender, EventArgs e)
{
Exception ex = Server.GetLastError();
Server.ClearError();
// Write exception to log
// redirect to error page
}
לולי הקריאה ל - ClearError האפליקציה תתרסק (עם הדף הצהוב הידוע) ולא ניתן יהיה להתעלם מהשגיאה או להפנות לדף שגיאה כללי.
באפליקציות windows forms ניתן לכתוב ב - Main את הקוד הבא:
Application.ThreadException += Application_ThreadException;
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
השורה הראשונה נרשמת לכל השגיאות הלא מטופלות מתוך תהליכים אחרים,
השורה השנייה נרשמת לכל השגיאות הלא מטופלות מתוך התהליך הראשי.
דוגמת קוד בסיסית תהיה כזו:
static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Show((Exception)e.ExceptionObject);
}
static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
Show(e.Exception);
}
internal static void Show(Exception e)
{
ExceptionMessageBox emb = new ExceptionMessageBox(e);
emb.Caption = "Error";
emb.Symbol = ExceptionMessageBoxSymbol.Error;
emb.Show(null);
}
צריך תמיד לזכור שטיפול נכון בשגיאות, וכתיבה שלהם לקובץ לוג חוסכת הרבה כאבי ראש ולב בעתיד.