65. rethrowing exceptions

מדי פעם אנחנו נתקלים בקוד כזה:

1
2
3
4
5
6
7
8
9
10
11
12
13
private static void Initialize()
{
try
{
LoadConfiguration();
// Do things here
}
catch (FileNotFoundException ex)
{
// Write to log.
throw ex;
}
}

עם מתודה מתאימה:

1
2
3
4
5
6
7
private static void LoadConfiguration()
{
using (StreamReader reader = new StreamReader("MyConfiguration.txt"))
{
// Do stuff here
}
}

כלומר אנחנו תופסים Exception, עושים כמה דברים וזורקים אותו מחדש.

הקוד לכאורה נראה תקין, אבל מתחבאת פה תקלה.

אם נסתכל הstack trace בexception שעף מהcatch block נראה exception שמתחיל מהמתודה Initialize:

at Initialize()
at Main(String[] args)

ולא מLoadConfiguration.

הדרך הנכונה היא לזרוק את הexception מחדש היא בצורה הבאה:

1
2
3
4
5
6
7
8
9
10
11
12
13
private static void Initialize()
{
try
{
LoadConfiguration();
// Do things here
}
catch (FileNotFoundException ex)
{
// Write to log.
throw;
}
}

שימו לב להבדל: השתמשנו בthrow בלי לציין את הexception שאנחנו זורקים.

זה אומר להמשיך את הזריקה של הexception שהרגע תפסנו בבלוק.

הstack trace כעת יראה כך:

at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath(
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize, FileOptions options)
at System.IO.StreamReader..ctor(String path, Encoding encoding, Boolean detectEncodingFromByteOrderMarks, Int32 bufferSize)
at System.IO.StreamReader..ctor(String path)
at LoadConfiguration()
at Initialize()
at Main(String[] args)

כמו שצריך.

המשך יום גשום טוב

שתף