none
Global Exception handling in WCF RRS feed

  • Question

  • In my application there are many services, I need to implement the exception handling in that. I cannot use try catch block in every method as this is a existing application with Remoting. I want to throw the actual managed exception like InvalidOperationException including full server stack trace to client so that client can log complete exception details. 

    Currently with includeExceptionDetailInFaults=True Client is receiving faultException with exception detail but not server's stack trace. Is there any solution which I can implement globally and client receive managed exception or fault exception with managed exception in InnerException with complete details.

    Sample code will very helpful.

    Thanks

    Thursday, October 30, 2014 12:30 PM

Answers

  • I don't want to make any change on method level as there are hundreds of methods, Can u suggest something which can be done on service or configuration level.

    What can I tell you. You should have dealt with this out the gate and not after the fact that you have already written code.

    Friday, October 31, 2014 3:07 PM

All replies

  • Yes, there is are way to achieve that but you need to change your service code. To your service send the exception details and even encapsulate the response you could do that:

    In your Service Contract Class:

    Use FaultContract to specify the Fault Message

            [FaultContract(typeof(BasicResponseMessage))]
            [OperationContract]
            string GetData(int value);
    

    Your fault message Data structure

     [DataContract]
        public class BasicResponseMessage
        {
            public BasicResponseMessage() 
            { 
            }
    
            public BasicResponseMessage(Exception ex)
            {
                Message = ex.Message;           
            }
    
            [DataMember]
            public int Code { get; set; }
    
            [DataMember]
            public String Message { get; set; }
        }

    In your Contract Implementation:

    You can return a bussiness error

      public string GetData(int value)
            {
                if (value < 10)
                    return string.Format("Você enviou: {0}", value);
                else
                    throw new FaultException<BasicResponseMessage>(new BasicResponseMessage { Code = 1, Message = "Valor maior ou igual a 10!" });
            }

    Or event an unhandled exception (ignore the code in try):

      public string GetData(int value)
            {
                try
                {
                    if (value < 10)
                        return string.Format("Você enviou: {0}", value);
                }
                catch (Exception ex)
                {
                    throw new FaultException<BasicResponseMessage>(new BasicResponseMessage(ex), new FaultReason(new FaultReasonText("Valor maior ou igual a 10!")));
                }
    
                return string.Empty;
            }

    Finally, in your client you can handle your specific exception, with treated message even the "original" exception.

    try
                {
                    var b = Proxy.GetChannel<IService1>().GetData(10);
                }
                catch (FaultException<BasicResponseMessage> faultEx)
                {
                }
                catch (Exception ex)
                {
                }

    Thursday, October 30, 2014 1:14 PM
  • What you need to do is use Request and Response object pattern where the exception is placed in the Response object, the object is sent back with DTO(s) for data returned in the Response object along with any exception messages if an exception occurs. You send the Response object over the WCF boundery between the client and the service and check for an exception in the returned Response object. 

    http://www.codeproject.com/Articles/91835/WCF-by-Example-Chapter-III-Response

    http://www.codewrecks.com/blog/index.php/2012/03/12/basic-request-response-wcf-service/

    You do the above to eliminate the headach of trying to catch exceptions thrown over the boundery.

    Thursday, October 30, 2014 2:40 PM
  • I don't want to make any change on method level as there are hundreds of methods, Can u suggest something which can be done on service or configuration level.

    I want either of one thing

    1. Through Managed exception like NullReferenceException from service with Stacktrace of server

    2. If above one is not possible than Fault exception with managed exception as inner exception of fault exception(Inner exception should contain full server stack trace).

    Thanks

    Friday, October 31, 2014 5:51 AM
  • I don't want to make any change on method level as there are hundreds of methods, Can u suggest something which can be done on service or configuration level.

    What can I tell you. You should have dealt with this out the gate and not after the fact that you have already written code.

    Friday, October 31, 2014 3:07 PM
  • I think you're after an IErrorHandler service behaviour.

    http://www.haveyougotwoods.ca/2009/06/24/creating-a-global-error-handler-in-wcf


    • Edited by SimonTaylor Wednesday, November 5, 2014 2:23 AM
    • Proposed as answer by SimonTaylor Wednesday, November 5, 2014 2:24 AM
    Wednesday, November 5, 2014 2:15 AM