13

Is it ok to let exception bubble up to the top of the stack instead of catching it in every method?.. Should we do it in any case? ..Are there any subtle issues or side effects with this approach (e.g. loss of details of the exception, stack trace or inner exception details etc.) ?


Though my question is general, the scenario in my case at present is as follows:

I am moving existing WSE3 web service to the WCF and so y clients are WSE3 clients.

I have added a behavior so that the FaultException will be communicated to the client side whenever it occurs in the WCF service. When there is an exception in the OperationContract method, I get exception message at client side without any problem. But whenever it occurs in the methods other than the OperationContracts, I get security related problem somehow. I am not able to identify the exact cause.

However, as a work around I thought to throw exceptions from OperationContract only and let exceptions bubble up to the OperationContract.

Learner
  • 4,661
  • 9
  • 56
  • 102

3 Answers3

17

Is it ok to let exception bubble up instead of catching it in every method?

Please Don't catch excpetions in every method! - you should only ever catch exceptions if you can do something useful with it, for example:

  • Handle it (i.e. not rethrow it)
  • Add some important contextual information

I've maintained applications where every nethod was surround with a try-catch block, and I literally mean every method:

public void DoSomething()
{
    try
    {
        throw new NotImplementedException();
    }
    catch (Exception ex)
    {
        throw ExceptionHandler.CreateException(ex, "DoSomething");
    }
}

Catching exceptions like this is utterly pointless and does nothing except make your code harder to read and your exceptions harder to trace.

In the case where you exception has to pass some interprocess boundary (such as in a WCF service) then at the point where your exception is exposed to the world you might want to first catch, log and then rethrow the exception in a compatible format for the IPC boundary so that you have a log of all failures in your servivce

In many cases however there is an alternative mechanism designed for just this purpose- WCF has the IErrorHandler interface which can be registered to catch and log all unhandled exceptions in a consistent way without needing a try-catch block in each exposed method.

Justin
  • 84,773
  • 49
  • 224
  • 367
  • 1
    In web service methods (SOAP), I do it similar to your code above: `try { ... } catch ( Exception x ) { log(x); throw; }` to have more logging on the server. I experienced that it helped me a lot to have the logging on _my_ side, not the customers/user's side of the SOAP service. – Uwe Keim May 03 '11 at 04:52
  • Thanks for the answer. But won't there be any side effects like losing the exception details (somehow)? Or other things if you can think of. – Learner May 03 '11 at 04:52
  • @CSharpLearner If you are crossing IPC boundaries (e.g. via SOAP web services) then you might want to add try-catch blocks, however many frameworks provide a more flexible way of controlling and logging thrown exceptions, for example WCF provides the [IErrorHandler](http://msdn.microsoft.com/en-us/library/system.servicemodel.dispatcher.ierrorhandler.aspx) interface. Is this what you are thinking of? – Justin May 03 '11 at 04:58
  • I have already implemented the the `IErrorHandler` and using that implementation only. But still I face the issue. I suspect it's because of the WSE3 client (not WCF client) communicating with the WCF service. – Learner May 03 '11 at 05:25
  • @CSharpLearner Do you have any specific examples? You might want to trace the exception using something like [Fiddler](http://www.fiddler2.com/fiddler2/) to see if the information is being sent which will identify whether the problem is with the client or the server. – Justin May 03 '11 at 05:29
9

Absolutely, that's what they're for. The rule of thumb is to catch the exception where you can make a sensible attempt at continuing. So, if you get something like an out of memory, let it bubble up and terminate the program; if you get a divide by zero as you iterate though a lot of data, catch it where you can go on to the next datum.

Update

In response to your question, no, all the details (including a stack trace where the exception was raised) are propagated with the exception object.

What you will see sometimes is something like

highLevelFunction(){
   try {
     lowerLevelFunction();
   } catch (LowLevelException e){
     throw HighLevelException(e);
   }
}

or exception chaining. What happens there is you have some low level exception like "divide by zero"; you catch it and raise a new exception like "data exception" to make it more meaningful to the routines that call highLevelFunction.

(PS forgive me if this isn't perfect C# syntax, I haven't written it much recently.)

Charlie Martin
  • 110,348
  • 25
  • 193
  • 263
  • Thanks for the answer. But won't there be any side effects like losing the exception details (somehow)? Or other things if you can think of. – Learner May 03 '11 at 04:48
3

If you have a full applications (GUI, business, data) let it bubble up to the UI and handle it here on the events. This gives you an opportunity to display a message to the user at the same time. It also catches it to the point of action origin (i.e. when user did action X this occured). Catching it in every method is too CPU intensive and unnecessary since you can just log the stacktrace to find the origin anyway. If you are making middleware application then try to handle it at the interface or bubble it out - depending on how the middleware will be used.

John S.
  • 1,937
  • 2
  • 18
  • 28