The following example violates the rule:
12 public void MyTest()
13 {
14 Process();
15 }
16
17 public void Process()
18 {
19 try
20 {
21 int result = Calculator.Divide(12, 0);
22 }
23 catch (DivideByZeroException ex)
24 {
25 // React, likely by logging
26 throw ex; // <- This is wrong
27 }
28 }
Executing this code results in the following logged callstack
...FxCopTests.Process() in C:\test\FxCopTests.cs:line 26 ...FxCopTests.MyTest() in C:\test\FxCopTests.cs:line 14Note that the callstack ends with line 26, which is in the catch block. In this example the real exception location isn't hard to find. Unfortunately, production code is rarely this simple.
The problem here is that calling "throw ex" causes the callstack info to be created at that point. If you were creating a new exception and throwing it this would be desired behavior. With an existing exception you don't want the original callstack to be overwritten.
The fix for this code is easy enough - replace:
throw ex;
with
throw;
After this change, the callstack correctly points to the line throwing the exception
...Calculator.Divide(Int32 x, Int32 y) in C:\test\Calculator.cs:line 11 ...FxCopTests.Process() in C:\test\FxCopTests.cs:line 26 ...FxCopTests.MyTest() in C:\test\FxCopTests.cs:line 14
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.