Exceptions are a very powerful concept when used correctly. An important cornerstone in the design of a good application is the strategy you adopt for Exception Management. You must ensure that your design is extensible to be able to handle unforeseen exceptions gracefully, log them appropriately and generate metrics to allow the applications to be monitored externally.
(Note: This article won the OSNews Aspire competition a few weeks ago.)
If you come are a COM background, you would know that there is not one way to generate and handle exceptions, which to me as a consumer and creator of components was a very painful task to handle. Just the different ways to deal with exceptions between c++ and VB would be enough to drive a sane person up the wall. Thankfully, in .NET provides a better approach to resolve the whole mess. The .NET Common Language Runtime (CLR) provides a uniform way to notify the different applications of an exception, even if they are written in different languages.
Understanding Exceptions
Most programmers who I have worked with that are either new to programming or do not come from an object oriented background (such as c++. Java, etc.) have a poor understanding of what an exception is. An exception is the violation of a contained assumption. E.g. your code tried to access a file that it assumes to be present, but if is not then an exception would be thrown. However if you application first checked to see if the file was present before trying to access it, then that scenario may not throw an exception.
It is important to understand is that an exception is not necessarily an error. The context in which an exception occurs within the application governs if it is an error or not.
All Exception classes should derive from the Exception base class. The exceptions can be created either by the runtime or programmatically by your application. All exceptions generated by the runtime are derived from the SystemException class (which ultimately derive from the Exception class). Your application’s custom exceptions should derive from the ApplicationException class which also derives from the Exception base class.
try<br>
{<br>
//try and do something here...<br>
}<br>
catch (SomeExeption ex) <br>
{<br>
//Handle the exception and take appropriate action<br>
}<br>
finally<br>
{<br>
//This code will *always* run irrespective if you have<br>
//an exception or not. Usually this is some clean up of<br>
//some sort though.<br>
}<br>
The try block has the code that could throw an exception and the catch block catches it. You can have more than one catch block and should be ordered from the most specific to the most generic in ascending order. The first catch filter that matches is the one that “catches” the exception, so it is important to keep the order in mind.
Exceptions vs. Errors
Exceptions are very expensive operation and should not be taken lightly (as most developers do). As a developer you need to understand the distinction between an exception and a error and when should you use one over the other. In general, you should throw an exception only when it violates some condition outside of your code.
Take the example where in your application you have an Update Profile screen (or page), where the user can update their profile with the user’s First and Last Name as required fields. In this scenario, throwing an exception when the user forgets to enter one of the required fields would not be a good practice, as this should be an expected condition for the application and should be handled via the normal flow of execution. However, if the database that the application connects with, to update the profile is not available is an Exception. Many developers get lazy here and treat everything as an exception.
The following example uses a if statement to check whether a connection is closed. You can use this method instead of throwing an exception if the connection is not closed.
if(conn.State != ConnectionState.Closed)<br>
conn.Close();<br>
In the following example, an exception is thrown if the connection is not closed.
try {<br>
conn.Close();<br>
}<br>
catch(InvalidOperationException ex) {<br>
//Do something with the error or ignore it.<br>
}<br>
The method you choose depends on how often you expect the event to occur. If the event is truly exceptional and is an error (such as an unexpected end-of-file), using exception handling is better because less code is executed in the normal case. If the event happens routinely, using the programmatic method to check for errors is better. In this case, if an exception occurs, the exception will take longer to handle.
Exception Propagation
There are typically three ways, on how to propagate an exception up the chain:
Designing your Exception Class
First and foremost, if an exception class already exists in the framework, use that instead of creating your own. You should typically only create a new exception for conditions that your code would need to handle and it is not already available either in the framework or an existing application exception hierarchy. A few things to keep in perspective when designing your application hierarchy:
[Serializable]
attribute and add the following constructor:protected YourBaseApplicationException(SerializationInfo info,StreamingContext context) : base(info, context)
Sample Base Application Exception:
public class YourBaseApplicationException : ApplicationException<br>
{<br>
// Default constructor<br>
public YourBaseApplicationException ()<br>
{<br>
}<br>
<br>
// Constructor accepting a single string message<br>
public YourBaseApplicationException (string message) : base(message)<br>
{<br>
}<br>
<br>
// Constructor accepting a string message and an <br>
// inner exception that will be wrapped<br>
public YourBaseApplicationException(string message, <br>
Exception inner) : base(message, inner)<br>
{<br>
}<br>
}<br>
Use Exceptions Wisely
Like I said earlier, exceptions are very expensive and it is best to use them wisely. There is a fine line in using them the proper way versus the “bad” way. A good example of what not to do which I come across very often is below.
public IDbConnection Open()
{<br>
try<br>
{<br>
Connection = new OracleConnection(this.ODSWebConnectionString);<br>
Connection.Open();<br>
<br>
return Connection;<br>
}<br>
catch(Exception exp)<br>
{<br>
throw exp;<br>
}<br>
}
In the example above, the code catches and exception just to rethrow it which adds a lot of overhead for something which does not do anything. In the above example, you should not have the try…catch block as it does not add anything else. If you want to understand all the steps involved (and why this is an expensive operation) refer to the Appendix.
Best Practices for “Consuming” Exceptions.
A well-designed set of error handling code blocks can make a program more robust and less prone to crashing because the application handles such errors. The following list contains suggestions on best practices for handling exceptions:
I would highly recommend using the Exception Application Block that is provided by Microsoft. The Exception Application Block provides a simple and extensible framework for logging exception information to the Event Log. You can also create your own components, to log exception details to other data sources or to notify operators, without affecting your application code.
This can easily be used as a building block in your own application. If you use it, you will reduce the amount of custom error handling code you need to create, test, and maintain. You will also make your application more robust and easier to debug. Specifically, the Exception Management Application Block will help you:
For more information and references please refer to the appendix.
Appendix
Please note that all the information in the appendix is from MSDN and .NET SDK. It is the copyright of their respective owners.
The following is a step-by-step description of how a first chance exception is handled:
Exception callback sequence
Microsoft has an excellent paper entitled Exception Management Architecture Guide.
About the Author
Amit Bahree is a Solution Architect in Cap Gemini Ernst and Young’s Advanced Development and Integration practice. He specializes in Microsoft technologies and platforms and can be reached at [email protected]. His blog can be found at http://www.desigeek.com
If you would like to see your thoughts or experiences with technology published, please consider writing an article for OSNews.
(Arghh! It working in the preview! Any change of an intelligent <code> tag support, it’d be okay if it chopped excessively long lines)
A powerful part of the exception mechanism is the finally block. This is ALWAYS executed, whether your program hits an error or not. Thus it is often used to free resources (dynamically allocated memory, database connections, network connections or files).
e.g. (from Java)
public static void copy(String[] args)
{
File inputFile = null, outputFile = null;
try
{ inputFile = new File(“farrago.txt”);
outputFile = new File(“outagain.txt”);
FileReader in = new FileReader(inputFile);
FileWriter out = new FileWriter(outputFile);
int c;
while ((c = in.read()) != -1)
out.write(c);
}
catch (FileNotFoundException fnfe)
{ // do stuff
}
catch (IOException e)
{ // do stuff
}
catch (Exceptione e)
{ // do stuff
}
finally
{ // whether the program worked or threw an
// exception, we close the files
in.close();
out.close();
}
}
In this way you’re guaranteed to close your files, no matter what happens. These finally blocks are incredibly useful, and are essential if you start doing socket or DB programming in modern OOP languages like Java or C#. They’re also essential to avoid memory leaks if you’re dealing with dynamic memory allocation like in C++ or Delphi.
This is kinda embarrassing, but the finally block should be
finally
{ if (inputFile != null) inputFile.close();
if (outputFile != null) outputFile.close();
}
So why can’t you just put the close statements after the catch blocks? They will be executed with or without exceptions.
in .Net, no code outside of a “catch” statement is guaranteed to run unless it’s in a “finally” block. Just comes w/ the framework, plus this lends itself to better coding practices.
You may exit the method in a catch block, or you may quit the program in a catch block. Whatever you do though, the finally block will always get called.
Also, as Jayson said, it’s considered better programming practice, it makes it explicit what resources you’re using and protects against other programmers altering, e.g. exception handlers, in the future.
exception in smalltalk are way better, cause they have #resum().
This mean that you can restart the processing from the exact method instead of a spurious block.
Even, exception’s statement modifer are really useful, too bad common .net languages do not use them :/
Please let’s not turn this into one more “language war”
in most instances, you have to put try/catch around close methods, because they throw IOException. this, in java, is *the* correct way:
FileReader in = null;
try {
in = new FileReader( “filename” );
// do stuff
} catch ( IOException e ) {
// print error
} catch ( FileNotFoundException e ) {
// print error
} finally {
if ( in != null ) {
try {
in.close();
} catch ( IOException e ) {
// print file close error
}
}
}
I did not meant to be rude, and I beg your pardon
I just believe that Exception#resume() is a wonderful tool, and I’d like to see it in more environments.
BTW people may argue that they are not good, I just wonder why.
Say, Ruby has first class reified continuations and it is quite easy to write a ResumableException class, yet this is not in the standard Exception’s , maybe matz has an answer :/
Only last week, I wrote about exceptions vs. error codes in my blog. I think a lot of times exception classes are created and exceptions thrown where only returning a status code would be the right thing to do.
http://www.livejournal.com/~mannu/164080.html
>This is kinda embarrassing, but the finally block should be
>finally
>{ if (inputFile != null) inputFile.close();
>if (outputFile != null) outputFile.close();
>}
Well, that works. But this form is much cleaner:
try{
inputFile = new File(“farrago.txt”);
outputFile = new File(“outagain.txt”);
try{
}finally{
inputFile.close();
outputFile.close();
}
catch(IOException e){
blahblah
}
The key is you don’t need all this if blah!=null business with the above approach. When you open a file or resource, always code your finally at that point. If an exception is throws on allocation/opening the resource your variables will stay null and you will not enter the try-finally block.
Hmm a good article about Exception.
This is ALWAYS executed
Well that’s not true:
try
{
//do something here
catch(Exception e)
{
//unrecoverable error, we loose
System.exit(1);
}
finally
{
// all resorces doesn’t get cleaned
System.out.println(“This is not executed in case of an exception”);
}
yeah, thats called “who guards the guards” scheme..
I find it surprising that neither the article nor the comments have mentioned the using block yet. It can greatly clean up code and simplify resource cleanup:
using (FileStream input = File.OpenRead (“input.txt”)) {
____using (FileStream output = File.OpenWrite (“output.txt”)) {
________// copy file contents
________byte[] buffer = new byte[256];
________int nread;
________while ((nread = input.Read (buffer, 0, buffer.Length)) != -1) {
____________output.Write (buffer, 0, nread);
________}
____}
}
(My apologies for using underscores for spaces, but it’s more legible than or not providing any indentation…)
No finally blocks, no worries about exceptions or resource cleanup, just plain code. Of course, if an exception is generated the exception will escape this code block (unlike the original Java version, which would swallow all exceptions), but the resources will still be disposed of cleanly, whether or not an exception is generated.
As in C++, the cleanest and most maintainable C# code doesn’t use try/catch explicitly for resource cleanup. C++ instead uses block-scoped objects with destructors, and C# offers the using block to simplify resource management. It would be advisable to use it whenever possible, to help remove code errors and other embarassments.
Finally, by implementing the System.IDisposable interface, you can implement your own resource cleanup strategies, which can be used for such esoteric things as locks with timeouts.
See also:
http://www.interact-sw.co.uk/iangblog/2004/03/23/locking
http://blogs.msdn.com/ericgu/archive/2004/03/28/100872.aspx
throwing null pointer exceptions is bad practice, nor should you nest the try in that way. i disagree. mainly because i, and my professors shun anything but that try/catch/finally/try/catch system
“(Note: This article won the OSNews Aspire competition a few weeks ago.)”
The poor writing and editing make me wonder what standards the OSNews Aspire competition adheres to. The technical content is lightweight enough, but the article is made much worse by horrible grammar and writing.
The rules of English composition are no more a matter of opinion or “style” than Java syntax is. Programmers should put as much effort into communicating with other people and less into showing off their mastery of technology.
Did you say:
“[i]Programmers should put as much effort into communicating with other people and less into showing off their mastery of technology.[i]”
I’m sure a master of grammar like yourself meant to say:
“[i]Programmers should put more effort into communicating with other people and less into showing off their mastery of technology.[i]”
Have a nice day
> but the article is made much worse by horrible grammar and writing.
As we explain in the competition, grammar does not matter, content does. This way, non-english people can also participate to our competition, otherwise, we discriminate, and that’s not never good.
I have a new problem with Exceptions: I need to manage the exception but I don’t have an error code to compare with, just messages. I can check a message to see if it has “timeout” then instruct my code to try again later, however, if the message is “not found” then I want to rethrow the exception or log it. This can work fine, but the real problem comes when I install this on a system that produces exception strings in another language like Chinese, then I can no longer catch and manage using the message string. Anyone, know how to handle this?
Different exceptions should have different types. That way, you can check the exception type instead of checking the message.
For your scenario, the throwing code should throw FileNotFoundExceptions and TimeoutExceptions (and any other distinct type which makes sense). This permits code like:
bool run = true;
int attempts = 0;
while (run) {
____try {
________FunctionThatThrows ();
____}
____catch (FileNotFoundException e) {
________// don’t bother retrying
________run = false;
____}
____catch (TimeoutException e) {
________// If it timed out, try again, but only re-try 5 times
________if (++attempts > 5) run = false;
____}
____catch (Exception e) {
________// unknown exception; don’t retry
________run = false;
____}
}
Ah yes, we really should use “WTF?????” or “WTF!!!! Why is this still happening?”
How would there be a null pointer excpetion?
Your and your profs don’t understand exception handling I guess.
try{
File file = new File();
try{
// use the file here
}
catch(IOException e)
{
// log or rethrow, or whatever here
}
finally{
file.close();
}
catch(FileCreateException fe)
{
// handle whatever the File open exceptions are here
}
Where are you going to get a null pointer exception in this scheme?
If an exception is thrown in the resource allocation (new File()), then execution will stop there and proceed to the catch FileCreateException. This is how it’s done by people who know what they are doing, I didn’t invent it.
In defense of both of you, give 10 developers the same problem, you will get at least 11 different solutions. Both ways work, it’s just a matter of style; is one way any better than the other? Well that would depends on your definition of better. Going the ultra nested try/catch/finally route eliminates the need for null pointer checking. Adding the null pointer checking eliminates the need for an nested level of try, et. al People that know what they are doing do it both ways. I’ve yet to see a solid argument for either side clearly showing one way it better than another. If some one has one, I liked to take a read
Doing the null checks is more error prone. and less clean. that’s it. the other way does work though.
He was saying my approach would throw null pointer exceptions though… and clearly it won’t. The reason people use the omnivector approach is 1) they don’t realize that the variable assignment doesn’t happen when an exception is thrown 2) they don’t undertand that execution ends at the point of the exception and either leaves the method or goes straight to the catch/finally block.