Home > SSW Standards > SSW Rules > Rules To Better Error Handling
Do you agree with them all? Are we missing some? Let us know
what you think.
-
Do you always avoid On Error Resume Next?
VB and VB.NET Only.
Never use On Error Resume Next in VB (and VB.NET) projects.
If an error occurred, On Error Resume Next will hide the error and things can
go very haywire! In .NET, stop using the On Error syntax and use the try-catch
exception syntax for better structural exception handling.
In VB/VBA you should use On Error Resume Next with line of comment and after
an offending line of code there should be statement On Error GoTo 0 to reset
Errors collection.
- Private Sub cmdSelect_Click()
Dim varTemp As Variant
On Error Resume
Next
varTemp = columnADOX.Properties("RelatedColumn").Value
.
....many lines of code...
.
intRoutesPerDay = 2
End Sub
-
Bad Example
- Private Sub cmdSelect_Click()
Dim varTemp As Variant
On Error Resume
Next
'Sometimes there is no related column value
varTemp =
columnADOX.Properties("RelatedColumn").Value
On Error GoTo 0
.
....continuing code...
.
End Sub
-
Good Example
-
Do you catch and re-throw exceptions properly?
A good catch and re-throw will ease you in debugging, a bad catch and re-throw will
ruin the exception's stack trace and make debugging difficult.
-
Bad:
- catch {}
(Never use an empty catch block. Do something in the block
or remove it.)
- catch (SomeException) {}
(Never use an empty catch block. Do something in the block
or remove it.)
- catch { throw; }
(Never use an empty catch block. Do something in the block
or remove it.)
- catch (SomeException) { throw; }
(Never use an empty catch block. Do something in the block
or remove it.)
- catch (SomeException ex) { throw ex; }
(Never re-throw exceptions by passing the original exception
object. Wrap the exception or use throw; instead.)
- catch (SomeException ex) { someMethod(); throw ex; }
(Never re-throw exceptions by passing the original exception
object. Wrap the exception or use throw; instead.)
- Bad code - The bad examples
-
Good:
- catch (SomeException ex) { someMethod(); throw; }
- catch (SomeException ex)
{
someMethod();
SomeOtherException wrapperEx = new SomeOtherException("This
is a wrapper exception", ex);
throw wrapperEx;
}
- Good code - The good examples
-
Do you use exception management application block?
In the past, we use our ErrorLogger component (written in COM/VB6) to collect errors
and send an email back to us. Now with .NET and the release of Microsoft's Exception
Management Application Block, we have implemented a WebServicePublisher for submitting
unhandled exceptions back to home base (that's us).
|
See how we configured this functionality with the Exception Management Block in
the .NET Toolkit.
|
-
Do you catch exception more precise?
In the try and catch block, if you always catch for normal "Exception" you will
never know where the true problem is. While we using try we should always expect
some exception may happen, in our code we always catch the specified exception.
-
Try
{
connection.Open();
}
catch (Exception ex)
{
return ex.ToString ();
}
- Bad code - Catch general Exception.
-
Try
{
connection.Open();
}
catch (InvalidOperationException ex)
{
return ex.ToString();
}
catch (SqlException ex)
{
return ex.ToString();
}
- Good code - Catch with specific Exception.
Implement Exception Management Application Block and let it
handles all unhandled and unexpected exceptions.
-
While everyone knows that "catch (Exception ex)" is bad, no one has really noticed that "throw Exception()" is actually the root of all evil.
System.Exception is a very extensive class, and it is inherited by all other exception classes. If you throw an exception with the code "throw Exception()", what you need subsequently to handle the exception will be the infamous "catch (Exception ex)".
As a standard, you should use an exception class with the name that best describes the exception's detail. All exception classes in .NET Framework follow this standard very well. As a result, when you see exceptions like FileNotFoundException or DivideByZeroException, you know what's happening just by looking at the exception's name. .NET Framework has provided us a comprehensive list of exception classes that can we can use. If you really can't find one that is suitable for the situation, then create your own exception class with the name that best describes the exception (eg: EmployeeListNotFoundException).
Also, System.ApplicationException should be avoided as well unless it's an exception related to the application. While it's acceptable and should be used in certain cases, be aware that using it massively will be just as bad as "throw (Exception ex)".
-
Do you name all your exception object as ex?
We suggested to use ex as all Exception Object.
-
catch
(SomethingException myException)
{
Console.Writeline(myException.message);
}
-
Figure: Bad example not using ex for the exception object.
- catch
(SomethingException ex)
{
doSomething();
throw;
}
-
Figure: Good example using ex for the exception object.
Acknowledgements
Adam Cogann
Cameron Shaw
Tim Fletcher
Edward Forgacs