A lot of the code base methods my peers have written perform their own error handling, usually by catching, notifying, and logging.
In these cases the methods return a boolean, indicating success or failure.
Sometimes though, if a method fails, I want the calling code to know why, and returning a boolean is not enough.
One way around this is to keep the error handling in the methods, but make the method void, and have the methods throw their Exceptions.
However, recently I've got into the habit of returning Exceptions in appropriate methods, usually action methods that could otherwise be void, but where I'd like to know the status of the action.
The advantages of returning an Exception over having a void method throw an Exception is that I think it makes it easier for other programmers to use your library, and, more importantly, it means you can safely call that method without having to worry about catching the Exception
For example, if the method is just void, it might not be instantly obvious that the programmer should handle success or failure.
But if the methods specifically specifies a return type of Exception, then you know you can check success or failure if you want to. But it also means you don't need to worry about catching the error if you don't want to.
Does that make sense? Maybe I haven't used the best example, but generally, is it OK to return Exceptions, or is there a better pattern out there?
UPDATE
wow, the overwhelming result is no way. I thought so. I must say, doing it (returning an Exception) kinda solved a problem, but it did feel wrong.
So, from some of your answers, the best solution to these specific scenarios (a complex class, or a class with one or more external dependencies (i.e. web service)) seems to be a custom results Class?
UPDATE:
I really appreciate all the opinions, I am reading through everything, and I'm thinking carefully about all the input.
Currently I'm favoring having a void method, throwing the Exceptions, and then catching them on the outside....is that better?
It is good practice to throw exceptions if you have appropriate exception handling. Don't blindly throw exceptions until the application crashes. In your option 1 example, an ArgumentException is more appropriate. Your option 2 is more appropriate for data validations.
Exceptions shouldn't be returned as a return value or parameter instead of being thrown. Don't throw System. Exception, System. SystemException, System.
Yes, throwing an exception causes the method to return immediately. However, it's not a normal return. For example, there is no return value. The only way to capture control from a method that is returning as a result of an exception being thrown, is to have an exception handler.
It is an essential concept never catch any exception so catch any exception only if you can handle it you can give additional contextual data in that exception. If you can't handle it in the catch block, then the best advice is don't catch it only to re-throw it.
If you mean something like ...
public Exception MyMethod( string foo )
{
if( String.IsNullOrEmpty() )
{
return new ArgumentNullException( "foo" );
}
}
... rather than ...
public void MyMethod( string foo )
{
if( String.IsNullOrEmpty() )
{
throw new ArgumentNullException( "foo" )
}
}
Then absolutely not, it is not okay to do that. You would be completely re-inventing the purpose of an exception and using it as an hresult. Here are some standard best practices.
Another good reason not to is that standard delegates would no longer match your method signature. So, for example, you could not use Action<string>
on MyMethod anymore and would need to use Func<string,Exception>
instead.
@Andy, per comment, answer too long for a comment: Not really. Don't be so concerned about the caller. He should be being defensive in his design anyway. Think about the semantics of an Exception ... "The execution of this application will stop right here unless somebody knows what to do about this problem." If you can resolve the issue, you should resolve it. If you can't, you have to log it and throw it to the next level, because they may know exactly what to do.
You should handle what you can handle and throw what you can't. By definition, the guy up the call stack has a broader view of the world than you. Your application needs to be resilient in it's ability to deal with exceptions and keep on going. They only way to do that is defensive coding and push issues up to higher levels of information to see if anything can be done.
At the end of the day if the answer is "no", then log the problem to it can be understood, be a good citizen of the box and terminate the application gracefully and live to fight another day. Don't be selfish and try and hide errors for your caller. Be defensive and he will do the same. :)
Check out the Enterprise Library Exception handling block. It think they really articulate a great vision for how to deal with exceptions throughout your architecture.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With