Following on from a recent post about 2 way recieve ports I thought i would look in a little more detail at how the different adapters return a fault to the client and what the differences are in how the client would manage the fault.
The scenario for this is as follows:
I have setup a simple scenario where the client will input a simple message and then an orchestration will return a fault back to the port. In this case the fault message has been typed as a string and I will always return the following message as the fault:
<?xml version="1.0"?>
<string>Custom Fault as 1 was the input</string>
As this is a fairly simple scenario im not going to put any screen shots up, but once the orchestration was deployed I setup a 2 way receive port, and then a bunch of receive locations (1 for each adapter type). The following table illustrates the results of the various scenarios and the configuration associated with each:
|
Adapter
|
Configuration
|
Exception Returned
|
Exception Message
|
Where is custom error?
|
|
HTTP
|
This was setup with the default configuration
|
N/A
|
N/A
|
No exception is thrown but the custom error message is returned as the message body returned from the adapter
|
|
SOAP
|
In the web.config of the published web service the ThrowDetailedError setting was set to false
|
SoapException
|
An exception is thrown by the Orchestration schedule
|
The custom error message is returned as xml but it is contained in the detail section of the Soap Fault. It can be accessed by the detail property of the SoapException.
|
|
SOAP
|
In the web.config of the published web service the ThrowDetailedError setting was set to true
|
SoapException
|
An exception is thrown by the Orchestration schedule
|
The custom error message is returned as xml, but it is contained in the detail section of the Soap Fault. It can be accessed by the detail property of the SoapException.
|
|
WSE 2
|
In the web.config file the following settings are set:
appSettings : ThrowDetailedErrors = true
WSE settings : detailedErrors = not enabled
|
SoapException
|
Server Unavailable Please try later
|
The custom fault string is not returned and is consumed.
|
|
WSE 2
|
In the web.config file the following settings are set:
appSettings : ThrowDetailedErrors = false
WSE settings : detailedErrors = not enabled
|
SoapException
|
Server Unavailable Please try later
|
The custom fault string is not returned and is consumed.
|
|
WSE 2
|
In the web.config file the following settings are set:
appSettings : ThrowDetailedErrors = true
WSE settings : detailedErrors = enabled
|
SoapException
|
System.Web.Services.Protocols.SoapHeaderException: Server unavailable, please try later ---> System.ApplicationException: An exception was thrown by the Orchestration schedule, Data Dump: <string>Custom Fault as 1 was the input</string>
at
<!—I have removed the full stack trace which was here à
|
The custom fault is buried within the Message property of the SoapException rather than separately within the detail section
|
|
WSE 2
|
In the web.config file the following settings are set:
appSettings : ThrowDetailedErrors = false
WSE settings : detailedErrors = enabled
|
SoapException
|
System.Web.Services.Protocols.SoapHeaderException: Server unavailable, please try later ---> System.ApplicationException: An exception was thrown by the Orchestration schedule, Data Dump: <string>Custom Fault as 1 was the input</string>
at
<!—I have removed the full stack trace which was here à
|
The custom fault is buried within the Message property of the SoapException rather than separately within the detail section
|
|
WCF-WsHttp
|
The following configuration settings were set:
Web.config : includeExceptionDetailInFaults = false
Adapter settings : includeExceptionDetailInFaults = true
|
FaultException
|
<?xml version="1.0"?>
<string>Custom Fault as 1 was the input</string>
|
The custom fault is returned as the Message property of the FaultException
|
|
WCF-WsHttp
|
The following configuration settings were set:
Web.config : includeExceptionDetailInFaults = true
Adapter settings : includeExceptionDetailInFaults = true
|
FaultException
|
<?xml version="1.0"?>
<string>Custom Fault as 1 was the input</string>
|
The custom fault is returned as the Message property of the FaultException
|
|
WCF-WsHttp
|
The following configuration settings were set:
Web.config : includeExceptionDetailInFaults = true
Adapter settings : includeExceptionDetailInFaults = false
|
FaultException
|
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
|
The custom fault is consumed and not returned to the client
|
|
WCF-WsHttp
|
The following configuration settings were set:
Web.config : includeExceptionDetailInFaults = false
Adapter settings : includeExceptionDetailInFaults = false
|
FaultException
|
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
|
The custom fault is consumed and not returned to the client
|
|
WCF-NetTcp
|
Adapter settings: includeExceptionDetailInFaults = false
|
FaultException
|
The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the <serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework 3.0 SDK documentation and inspect the server trace logs.
|
The custom fault is consumed and not returned to the client
|
|
WCF-NetTcp
|
Adapter settings: includeExceptionDetailInFaults = true
|
FaultException
|
<?xml version="1.0"?>
<string>Custom Fault as 1 was the input</string>
|
The custom fault is returned as the Message property of the FaultException
|
Based on the results above my thoughts on this are as follows:
HTTP Adapter:
1. The custom fault is returned as the message body
2. The server status code is OK when a fault is returned so a client would have to determine from the message that there was a problem. But you would kind of expect this over HTTP
Soap Adapter:
1. The ThrowDetailedError setting in the appSettings in the web.config seems to have no effect
2. The custom fault is always returned as the detail section of the Soap Fault
WSE Adapter:
1. To make the WSE adapter return your custom fault string you need to turn on the WSE detailed errors in the wse section web.config file.
2. The ThrowDetailedErrors in the appSettings section seems to have no effect.
3. You would have to parse the exceptions message to get the custom fault string as it is in the middle of the message. This makes the response much less client friendly when compared to the Soap Adapter.
WCF Adapter (wsHTTP & NetTcp):
1. There is a new exception (FaultException) which is thrown.
2. The configuration is based on what is configured in the adapter settings held in SSO
3. The adapters seem to have a consistent approach unlike WSE/Soap which is useful
I may extend this to include some of the other WCF adapters, but it is nice to see that they seem to follow a consistent approach to handling this. Again this highlights another issue with the frustrating WSE adapter, im not sure why the custom fault was buried in the message as this has no value in being in this section when the Detail property is for precisely this reason.
Disclaimer
I have noticed a few sites that seem to copy the content of blog articles and display them in their own site. It is a bit annoying that they do not clearly reference or acknowledge the author so I have decided to put this note on the bottom of all of my posts from now so it is clear who wrote it.
This article was written by: Michael Stephenson
The source of this article is: http://www.geekswithblogs.net/michaelstephenson