Returning Errors



Returning Errors

Like any programming protocol or language, SOAP defines how error handling should occur; and like other Web protocols, SOAP assumes that errors will happen. The basic mechanism for handling errors with SOAP is the SOAP fault. With this special element structure defined in the SOAP specification, any SOAP node can send a fault to any other node to indicate some kind of failure.

In .NET, you can return SOAP faults from a server, and you can catch them on the client. In both cases, the SoapException object is how it is done. Also, if you throw another type of exception from your server, then this exception will be wrapped as a SoapException.

[WebMethod] 
public double Divide( double x, double y)
{
     if( y == 0 )
     {
          throw new Exception("Can not divide by zero.");
     }
     return x / y;
}

This code will end up sending a SOAP fault, as in Listing 3.22.

A SOAP Fault
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode>soap:Server</faultcode>
      <faultstring>System.Web.Services.Protocols.SoapException: Server!! was unable to process request. ---&gt; System.Exception: Can not divide by zero.
   at ExceptionE.Service1.Divide(Double x, Double y) in c:\inetpub\wwwroot\exceptione\service1.asmx.cs:line 59
   --- End of inner exception stack trace ---</faultstring>
      <detail />
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

Notice that the <faultcode> element indicates that this is a server error. Also, the <faultstring> element contains the usual exception string. The <detail> element is empty, but you can set it on the server, as shown in Listing 3.23.

A Method with SOAP Fault Modifications
[WebMethod]
public double Divide( double x, double y)
{
     if( y == 0 )
     {
          XmlDocument doc = new XmlDocument();
          doc.LoadXml("<BadStuff>You shouldn't try to divide by  zero.</BadStuff>");
          XmlQualifiedName code = new XmlQualifiedName("Sample", "http://sample");
          SoapException ex = new SoapException("Can not divide by zero", code, "TheActor", doc );
          throw ex;
     }
     return x / y;
}

This XmlDocument will result in a SOAP fault that looks like Listing 3.24. Notice that the <detail> element is missing. You will need to include that in your XmlDocument if you want the extra XML to appear in the SOAP.

A SOAP Fault Message with Detail Information
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope
     xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
  <soap:Body>
    <soap:Fault>
      <faultcode xmlns:q0="http://sample">q0:Sample</faultcode>
      <faultstring>System.Web.Services.Protocols.SoapException: Can not divide by zero
   at ExceptionE.Service1.Divide(Double x, Double y) in c:\inetpub\wwwroot\exceptione\service1.asmx.cs:line 66</faultstring>
      <faultactor>TheActor</faultactor>
      <BadStuff>You shouldn't try to divide by zero.</BadStuff>
    </soap:Fault>
  </soap:Body>
</soap:Envelope>

NOTE

The Application_OnError event will not get called from a Web service.