Does Exception Shielding work when implementing WCF REST?

Topics: Exception Handling Application Block
Jan 6, 2011 at 5:53 PM

I am still in the beginning process in attempting to learn and implement the new Enterprise Library 5 application blocks. I read there is support for exception shielding WCF services and am wondering if this will work for WCF RESTful services as well, or will it require SOAP?

Jan 7, 2011 at 7:09 AM

I haven't worked on a REST wcf service but based on some reading, I don't think EHAB's exception shielding would work on it, or at least the out of the box behavior, I'm not sure.  I did try it and verified it doesn't works just like in a regular WCF service.  I'm still doing some reading and I'll let you know if I do find out anything helpful.  

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 7, 2011 at 4:05 PM

Thanks, Sarah. I am anxious to hear what you find. Because we are using WCF to support our mobile apps running on iPhone, iPad, etc., we have no choice but to use REST. It would be great if we can find a way to use EntLib for exception shielding.

Jan 7, 2011 at 4:46 PM

Same situation for me.  Anxious to hear the answer :)

 

Jan 10, 2011 at 5:27 AM
Edited Jan 10, 2011 at 5:27 AM

I was unable to find much discussion regarding exception handling with REST, especially on how the client catches or determined the occurrence of the exception.  I found this blog and found out that the exception isn't something that is detected at the client using try catch block.  If you could point me to a link which would directly help me on this or provide me a sample code on how you are able to determine the exception on the client side, I could do more investigation on this.  Pardon as I haven't really tried consuming or creating a WCF REST service (the testing I mentioned before was done using a sample REST service I just downloaded)

 

Sarah Urmeneta
Global Technologies and Solutions
Avanade, Inc.
entlib.support@avanade.com

Jan 14, 2011 at 6:10 PM

I am catching Exceptions from the Implementation layer and casting them as a WebFaultException. This probably should log the original exception and shield it by creating a more generic WebFaultException message before throwing it.

For example:

[WebDispatchFormatter]
[WebHelp(Comment = "Return patient Treatment Authorization list")]
[WebGet(UriTemplate = "GetMedAuthList")]
public List<EmpMedAuthSummary> GetMedAuthList()
{
    var ret = new List<EmpMedAuthSummary>();

    try
    {
        ret = impl.GetMedAuthList();
    }
    catch (Exception ex)
    {
         throw new WebFaultException<string>(ex.Message, (HttpStatusCode)ex.Data["HttpStatusCode"]);
    }

    return ret;
}

Jan 19, 2011 at 4:07 PM

Well, I set up a short test and it appears that it will not work if using WCF REST Contrib, which I was forced to do because of limitations in the native WCF version. Hopefully, as additional features are baked in as first class citizens, this shortcoming can be addressed. With the popularity of Mobile devices that are largely RESTfull by nature, this will become increasingly important.

My test code is as follows:

namespace Domain.Abstract
{
    public interface IThrowAnErrorRepository
    {
        string ThrowAnError();
    }
}

namespace Domain.Concrete
{
    public class ThrowAnErrorRepository : IThrowAnErrorRepository
    {
        public string ThrowAnError()
        {
            throw new ArgumentNullException("Testing null exception handling");
        }
    }
}

namespace Domain.Entities
{
    [DataContract]
    public class ServiceFault
    {
        [DataMember]
        public Guid FaultID { get; set; }

        [DataMember]
        public string FaultMessage { get; set; }
    }
}

namespace Application.Interfaces
{
    [ServiceContract]
    public interface IPublicWcfExceptionTest
    {
        [OperationContract]
        [FaultContract(typeof(ServiceFault))]
        void TestExceptionBehavior();
    }
}

namespace Application.Library
{
    [ExceptionShielding("WcfPolicy")]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    public class PublicWcfExceptionTest : IPublicWcfExceptionTest
    {
        public void TestExceptionBehavior()
        {
            var repository = new ThrowAnErrorRepository();
            repository.ThrowAnError();
        }
    }
}

namespace WcfService
{
    public class Global : System.Web.HttpApplication
    {
        internal void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes();
        }

        private void RegisterRoutes()
        {
            RouteTable.Routes.Add(new ServiceRoute("PublicWcfExceptionTestSvc", new WcfRestContrib.ServiceModel.Activation.WebServiceHostFactory(), typeof(WcfService.PublicWcfExceptionTestSvc)));
        }
    }
}

namespace WcfService
{
    //[ServiceAuthentication]
    [ExceptionShielding("WcfPolicy")]
    [ServiceConfiguration("DeviceIdRestBehavior", true)]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
    public class PublicWcfExceptionTestSvc : IPublicWcfExceptionTest
    {
        [Description("Test WCF REST Exception Shielding")]
        [WebGet(UriTemplate = "TestExceptionBehavior")]
        public void TestExceptionBehavior()
        {
            var impl = new PublicWcfExceptionTest();
            impl.TestExceptionBehavior();
        }
    }
}