Reputation: 10247
I was using the following pattern for catch blocks in my data class:
} catch (OracleException e) {
log.Error(e, e);
ExceptionNotification.Show(e, "Platypus data not found for Platypus");
throw;
}
(the "log" is log4net; after that is our fancy exception display dialog).
When I remove the "throw," I get "not all code paths return a value"
If I reach the exception block, the object I want to return (an OracleDataTable, a List, a Dictionary<>, or a custom class, usually, might be null, or at best not feeling too well. What can I return to mollify the compiler?
Upvotes: 2
Views: 203
Reputation: 113242
Never mollify compilers. Boss them around and make them do what you need, or they'll get above themselves.
Compilers have a submissive nature, and like being bossed; the moment you start mollifying them they stop helping you. Some of them even bring their own paddles.
If you have to ask this question, you're probably taking the wrong approach. The answer to "what value to return on swallowing an exception" is "the value that is blatantly obvious as the value to return in swallowing this exception in this place". If nothing is that obvious, then it shouldn't be swallowed (the same applies to "the obvious place in the loop to continue from after swallowing this exception in this place"). And then double-check your assumptions because the "obvious" thing can still be wrong.
You should also comment any swallowing clearly, because it's so often a bad thing that anyone reading the code is going to start with the assumption that it's bad code unless you explain why it isn't.
You're better off with one of the following:
throw;
Let the exception pass up. Something handles it, or something doesn't and you get an error message and a shut-down (not always the worse thing, depending on the application and how likely the error seemed to be).
throw e;
Which would throw the exact same exception (literally the same instance) but will be seen as coming from your code rather than the code you called into. This is so rarely the right thing that some people will tell you it's plain wrong. I disagree, but I do agree the cases are rare - like swallowing, if it isn't the obvious choice it's almost certainly the wrong choice and if it is the obvious choice it might still be the wrong choice.
throw new ExceptionTypeAppropriateToThisMethodCall("a useful message");
OR
throw new ExceptionTypeAppropriateToThisMethodCall("a useful message", e);
Here you turn the exception into something more closely related to the service your method supplies to the calling code. The second form wraps the inner exception for diagnostic goodness.
In some cases, just killing the application or unloading the app-domain can be the best choice, though that's mostly going to happen from not having anything handle the exception at any point.
Upvotes: 2
Reputation: 150108
Every code path of a method that declares a return type must either return a value or throw an Exception.
If you don't want to throw, you must return an appropriate value
} catch (OracleException e) {
log.Error(e, e);
ExceptionNotification.Show(e, "Platypus data not found for Platypus");
return SomeMeaningfulReturnValue;
}
However, unless the value you can return is actually meaningful to the caller (as opposed to say returning null and inventing a code contract that "null means there was a problem), I would stick with the convention of throwing an Exception when something exceptional goes wrong.
Upvotes: 5
Reputation: 16651
Well, you either throw an exception or return a value. That's why the compiler is complaining. You need to decide which pattern works best in your particular case, adopt it and make sure that the calling code is written to take it into account. In this particular case I would probably just propagate the exception, since you are catching an exception. Unless you're compensating somehow for unruly behavior of the Oracle driver that is throwing exceptions when it probably shouldn't.
"I didn't find any data" or similar situations are not equivalent to "I couldn't log on to the database because the password was wrong".
Upvotes: 1
Reputation: 62246
What can you return depends on what you want your function do on failure, or what the caller of that function expects like fault sign.
You can add return null
(considering your post), to
first notify to a caller that returning value is null
second do not propagate exception (cause that is what you want, as much as I understand)
Upvotes: 1