Sek wrote:
I was pondering over a code and noticed that exception handlers were
present in the private, protected as well as public methods. And,
ofcourse, public methods were calling priv/prot methods internally.
My thought was, the exception is being rethrown and propagated by the
non-public methods to the public methods, causing performance overhead
(stack winding etc).
I do agree that, the purpose of throwing the exception by internal
methods and the need for such exception in public methods is the
deciding factor.
I have no idea what you mean by that last sentence. A method will throw
an exception when something happens that its author decided as
"exceptional" and not part of the normal functioning of the method.
Someone passing an invalid argument is a good example.
The difficulty is that when writing a library method that will be used
on other projects, it's sometimes difficult (or impossible) to decide
what constitutes "exceptional". What may be exceptional to one
application may be business-as-usual for another. In situations like
this, you have three choices:
1. Code the error as a return value and therefore assume that all
callers will check the return. This is old-school but it is perfectly
valid in C# and used by the .NET Framework in many places.
2. Code the error as an exception and have any callers that want it to
be business-as-usual catch the exception.
3. Code the error as an exception and provide another routine to check
pre-conditions, so that callers who consider the error
business-as-usual can call the check routine first. (This is done in
the .NET Framework 2.0 with Parse() and TryParse().)
Fortunately, these situations are relatively rare. It's usually pretty
clear what constitutes an exceptional situation and what doesn't, which
is why most C# code should have very few catch clauses.
But, won't it be better to avoid using try-catch handlers in non-public
methods and rather handle these exceptions only in public methods.
It's better to avoid try-catch everywhere, except when they add value.
You should be catching exceptions only when you know you can do
something useful with them.
Commonly, folks do use try-catch handler in every non-public
method(generally thought of as a safety measure!).
Good grief, no! There is no "safety" in catching an exception with
which you can do nothing useful. Let it bubble up the stack and crash
your program, and write global exception handlers to log such
exceptions. If you have try...catch in every non-public method (or in
every method), all you're doing is obscuring errors in your
application.
So, wouldn't it be appropriate to have try-catch handlers in public
methods alone and avoid the catch-rethrow practice in non-public
methods?
Catch-rethrow has its uses, but it certainly shouldn't be applied
willynilly. Catch-rethrow is useful when:
1. The exception you're catching makes no sense in the context of your
method. That is, a lower-level method throws an exception that makes
sense because of what that method does, but it wouldn't make any sense
to your caller, so you catch it, wrap it in a more appropriate type of
exception, and throw that.
2. You can add valuable information about your context that will help
debug problems. Again, catch the exception, wrap it in another
exception with more information, and throw the new exception.
3. You want to inspect the exception to see if it's one that you can
handle. This is usually based on the exception's type, and thus the
catch clause, but sometimes it isn't, and you may decide to handle the
exception, or rethrow it, in which case use throw, not throw ex.
4. You want to throw it later. For example, you may be doing 100
operations, and #54 fails. You may want to store that exception and
re-throw it after all operations complete, most likely wrapping it in
another exception in the process.
....and probably more I haven't thought of. However, one doesn't catch
and re-throw "just because".