Exception handling in API questions
I am writing an API in C#. Some exceptions in some methods I propagate, because I want the user to see be aware of the exception. However, some exceptions I don't. To let the client aware, do I need to propagate from the method and in every callee of that method? E.g.
a > c开发者_JAVA技巧alls b > calls c
if I rethrow from c, do I need to do the same from b and from a?
Also, an exception caught in a method's catch block (say, b, called from a) will also be caught in a's catch block. But what would be the difference if a is the entry point to an API and b has throw ex; in the catch block?
Thanks
The first rule of exception handling: don't catch an exception unless you know what to do with it. There's no point in having code that looks like catch (Exception ex) { throw ex; }
.
if I rethrow from c, do I need to do the same from b and from a?
No, you don't. Any exceptions thrown by c
will automatically bubble up the call stack, via b
and a
and back into the client code.
Also, an exception caught in a method's catch block (say, b, called from a) will also be caught in a's catch block.
That's not true: if b
catches an exception, a
won't see it unless b
rethrows it.
But what would be the difference if a is the entry point to an API and b has throw ex; in the catch block?
If b
catches an exception then re-throws, then both a
and the client will see that exception.
By the way, throw ex;
is bad practice. Exception
objects keep track of the call stack from where they were thrown. throw ex;
erases this call stack which makes it hard to debug the underlying cause of the exception. Instead, to re-throw an exception you've caught, use throw;
.
I think it's much simpler than you try to describe: If an exception is thrown, it goes the call stack up until it gets catched. If it's not catched at all, the program terminates. If an exception is catched, it is up to the catch block to decide how to continue. The options are:
- Handle the situation somehow and don't throw again. In that case execution just continues after the catch block.
- Rethrow the exception. In that case the exception continues to walk up the call stack until the next catch block is hit.
- Throw another exception: Same as 2. but with throwing a different exception. Often the new exception holds the original one as inner exception. That way the client of your API gets an idea where the exception originally came from.
First, you should only catch an exception if you intend to handle it. This can include logging, if necessary.
If you catch it, but want to re-throw, use:
throw;
not
throw ex;
You will have to repeat this each time the exception is caught. So you might have to do it in b
and a
, for your example, if both catch it.
For this question "do I need to propagate from the method and in every callee of that method?" The answer is no, you don't have to catch the exception in each method in the process, the best practice is to put a try catch whenever you cal an external code, in your case, each call to the api. after you catch exception you can:
- handle the error by yourself.
- re throw a new custom exception you create.
精彩评论