none
Implemeting IErrorHandler and ErrorBehaviorAttribute Vs AppDomain.CurrentDomain.UnhandledException RRS feed

  • Question

  • Hi All,

    I want to capture all the unhandled exceptions occuring during the service call and I would like to do it in a most performant way. I did some research and created

    public sealed class ServiceErrorHandler : IErrorHandler

    and

    public sealed class ErrorBehaviorAttribute : Attribute, IServiceBehavior

    I used the attribute on service implementation

    [ErrorBehaviorAttribute(typeof(ServiceErrorHandler))]
        internal class CatalogDataProviderService : ICatalogDataProviderService

    Then I had a discussion about the performance with my coworker and we thought tapping into Appdomain UnhandledException will be better for performance.

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    I would like to get your comments and suggestions on this. All the threads I read are showing the example for IErrorHandler, so it would be great if you guys can shine some light on this for us.

    Thank you

    Wednesday, May 13, 2009 10:01 PM

Answers

  • -> And in this method (CurrentDomain_UnhandledException) transform the exception to  FaultException<TDetail> , log it then throw it.

    When UnhandledException is propagated to the AppDomain level which will unload the whole AppDomain, it doesn't make sense to transform the exception into FaultException, since the whole WCF service runtime is unwound, and you actually don't need to throw from AppDomain.UnhandledException, since UnhandledException event will be called as part of the undeniable unhandled exception progation which eventually will torn down the whole process, just log the error and go.

    Thanks
    Marco

    Another Paradigm Shift
    http://shevaspace.blogspot.com
    • Marked as answer by Celik Monday, May 18, 2009 7:18 PM
    Friday, May 15, 2009 3:48 AM
  • by the time the AppDomain event gets fired you are too late to do anything other than log the issue - it's not an exception handler, its an event to tell you an exception wasn;t handled. So IErrorHsndler is the central point to be able to generate faults to the client
    Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
    Twitter: richardblewett
    • Marked as answer by Celik Monday, May 18, 2009 7:18 PM
    Monday, May 18, 2009 7:02 PM
    Moderator

All replies

  • You are comparing applies and oranges.

    Error handlers are there to allow you to centralize the mapping of exceptions to fault messages. WCF has already *handled* the exception. If you don;t provide a fault it will fault the channel for the client.

    AppDomain.UnhandledException allows you to take action if the application does handle an exception. It doesn;t allow you to actually *handle* the exception though - the application will still terminate


    Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
    Twitter: richardblewett
    Thursday, May 14, 2009 12:02 AM
    Moderator
  • Thank you for the reply Richard,

    When I am using IErrorHandler  I have the following code logic


    public bool HandleError(Exception error)
    {
         return true;
     }

    public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
    {

                if (error is FaultException)
                {
                    return;
                }
                else
                {
                               //Some code to create our own Fault detail object and assign it to FaultException<TDetail>
                 }
    }


    Through out the code I catch specific exceptions and transform them to FaultException<TDetail> and log them , TDetail being our inhouse fault detail object , but   any exception which is not cought previously will be turned into FaultException in this ProvideFault method. I know WCF can do this automatically but I need to log the errors and transform them to simple user messages.

    So in that case you are very right saying that exception is already handled and I am just checking what type of exception it is and if it is anything other than FaultException I transform it.

    On the unhandled exception case

    I  am thinking much on the lines of

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    And in this method (CurrentDomain_UnhandledException) transform the exception to  FaultException<TDetail> , log it then throw it.


    So in these two cases which one will be more performant?

    My concern with the performance comes into play thinking that if I choose the IErrorHandler  way with [ErrorBehaviorAttribute(typeof(ServiceErrorHandler))]
    , every time a method is called from CatalogDataProviderService, ApplyDispatchBehavior method is going to get called (see below code) which is going to degrate the performance.

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
            {
                IErrorHandler errorHandler = (IErrorHandler)Activator.CreateInstance(_handlerType);

                foreach (ChannelDispatcherBase chanDisp in serviceHostBase.ChannelDispatchers)
                {
                    ChannelDispatcher disp = chanDisp as ChannelDispatcher;

                    disp.ErrorHandlers.Add(errorHandler);
                }
            }


    I hope I am little more clear on the issue. I am trying to find out the best practice on this, as I said before for the best performance.

    Thank you

    Thursday, May 14, 2009 2:28 PM
  • -> And in this method (CurrentDomain_UnhandledException) transform the exception to  FaultException<TDetail> , log it then throw it.

    When UnhandledException is propagated to the AppDomain level which will unload the whole AppDomain, it doesn't make sense to transform the exception into FaultException, since the whole WCF service runtime is unwound, and you actually don't need to throw from AppDomain.UnhandledException, since UnhandledException event will be called as part of the undeniable unhandled exception progation which eventually will torn down the whole process, just log the error and go.

    Thanks
    Marco

    Another Paradigm Shift
    http://shevaspace.blogspot.com
    • Marked as answer by Celik Monday, May 18, 2009 7:18 PM
    Friday, May 15, 2009 3:48 AM
  • Thank you for the reply Marco,

    You made a very valid point about NOT throwing the exception again if it is caught using the below code

    AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);

    And in this method (CurrentDomain_UnhandledException) transform the exception to  FaultException<TDetail>


    When I use AppDomain.CurrentDomain.UnhandledException , is there any way that I can inform the client about the exception occured on the service side by means of soap exception ? That was my intension to transform and rethrow so the client can get a FaultException.

    Or do you recommend using the other option I listed by using IErrorHandler  ?

    My goal is to be able to handle all the exceptions thrown on the server side , log it and inform the client by means of soap exception and a unique reference number to the exception so the exceptions that client received from the service can be traced down to a specific exception in the log file.

    If by using AppDomain.CurrentDomain.UnhandledException I should not throw any other Soap exception to inform the client, then using IErrorHandler  is the best way to go for me.

    Do you agree ? I am open to suggestions.

    Thank you.
    Monday, May 18, 2009 5:11 PM
  • by the time the AppDomain event gets fired you are too late to do anything other than log the issue - it's not an exception handler, its an event to tell you an exception wasn;t handled. So IErrorHsndler is the central point to be able to generate faults to the client
    Richard Blewett, thinktecture - http://www.dotnetconsult.co.uk/weblog2
    Twitter: richardblewett
    • Marked as answer by Celik Monday, May 18, 2009 7:18 PM
    Monday, May 18, 2009 7:02 PM
    Moderator
  • Thank you Richard and Marco, I have better knowledge to make a decision with both of your posts.
    Monday, May 18, 2009 7:17 PM