I was reading up on exception handling tonight — looking for a way to prevent crashes in a Windows Service which sports a plugin architecture (whether or not the crashes should be prevented if there is a way) — when I found this code:
1 2 3 4 5 6 7 8 9 10 11 | Resource resource = GetResource(); try { DoWork(); return resource; } catch { DisposeResource(resource); throw; } |
There are two flaws with this code.
- Exceptions are being used to control the logic under normal conditions.
- Unmanaged exceptions will be caught by the catch block.
That’s bad. However, both of those points can be over looked because this snippet respects the stack trace. What does that mean? Consider the following code:
1 2 3 4 5 6 7 8 9 | try { return 1 / 0; } catch (Exception ex) // or catch (DivisionByZeroException ex) { // clean up or logging throw ex; } |
In this second example, a method invoking the above code will still get an exception however the stack trace will indicate the line number of “throw ex;” instead of the original line “return 1 / 0;”. This makes debugging from an exception log virtually impossible. Here’s a great article to read about best practices concerning .NET exceptions.
Always respect the stack.