I have handled exception in wcf using Fault Contract but interviewer asked Can we do exception handling in WCF without using the FaultContract? If Yes then how?
MyException fault = new MyException("Error message");
throw new FaultException(fault, new FaultReason("Reason Text"));
Related
I have a workflow service. I also use workflow persistence in that service. But after I deployed workflow in IIS, from client I make a request to workflow service, in log file on server. I see a message
The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}SaveWorkflow was interrupted by an error.InnerException Message: Type 'System.ServiceModel.Channels.ReceivedFault' cannot be serialized.
Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute.
If the type is a collection, consider marking it with the CollectionDataContractAttribute. See the Microsoft .NET Framework documentation for other supported types.
I tried research about this exception, but I didn't find anything.
How to fix this problem ? or let me know what is the reason about above exception ?
System.ServiceModel.Channels.ReceivedFault is a non-serializable internal .NET framework class, so unfortunately there is nothing you can do to correct the actual root cause (i.e. making said class serializable).
You are probably calling an external service via WCF which faults, i.e. a System.ServiceModel.FaultException is thrown. IIRC, somewhere deep down in that FaultException object is a reference to the culprit, a ReceivedFault instance.
Solution: Catch all FaultExceptions, transfer the information you need to know from the FaultException into a serializable exception, and throw the latter:
try
{
CallService();
}
catch (FaultException ex)
{
// Gather all info you need from the FaultException
// and transport it in a serializable exception type.
// I'm just using Exception and the message as an example.
throw new Exception(ex.Message);
}
I have a camel-cxf webservice up. I use to handle all SOAP Faults in the CXF's SOAP Fault Interceptor mechanism. That is working well.
I thought that its better to handle Exception thrown at the Camel layer at the same layer and wrote a simple onException scenario like this:
onException(Exception.class).
to("direct:MyWSExceptionHandler");
Whenever a custom exception is thrown, I was expecting the onException to kick in(Remember I also have a SOAP Fault Interceptor too), but it doesn't. The CXF is taking over and the message is going through the Interceptors, rather than the Camel Route.
Is this the expected way, or am I doing something wrong?
My CXF fault interceptor looks like this:
#Component("SOAPFaultInterceptor")
public class SOAPFaultInterceptor extends AbstractPhaseInterceptor {
public SOAPFaultInterceptor() {
super(Phase.MARSHAL);
}
public void handleMessage(Message message) throws Fault {
// The message is coming here directly, instead of going to the route defined by onException.
}
}
Can someone please tell how to fix this? I don't want Exception generated at the Camel layer to leave that layer without being handled..
Thanks in advance.
Camel's onException only triggeres if there is an exception. A SOAP Fault is represented as a Message with the fault flag = true.
What you can do is to set handleFault=true on CamelContext, then it will turn SOAP fault messages into an exception that the onException can react upon.
I have a WCF service deployed on two or more remote machines and there is a desktop based application that is used by the client to access any wcf service.
The WCF service is connected to SQL server 2005 to read and write data.
This is an intranet scenario in which the client should be on same domain.
Now there can be scenarios where the wcf service throws exceptions:
Invalid URL
WCF service is down
SQL server 2005 is not running
Client is not on the same domain
Authentication fails
Authorization fails
and many other exceptions.
For every exception I have to perform some action or update a status bar, depending on the exception. For example if authorization fails I have to prompt the user to re-enter their credentials.
Please suggest the best design approach to handle this.
You can definitely catch and handle all exceptions that happen on your service class and turn them into a FaultException or FaultException exception.
That way, you won't "fault" (or tear down) the communications channel between your client and server.
Even better approach would be to implement the IErrorHandler interface on your service class that provides a way to globally catch all exceptions as they happen and provide a FaultException instead, that's SOAP compliant.
You can even turn your IErrorHandler into a configurable behavior that can be turned on or off in config.
See these articles and blog posts for more details:
Rory Primrose: Implementing IErrorHandler
Useful WCF behaviors: IErrorHandler
Create a custom fault class that is marked with the DataContract attribute
Mark the method on the service contract interface with FaultContract. Ie. [FaultContract(typeof(CustomFault))]
In your service method, catch any applicable internal exceptions and throw a FaultException<CustomFault>. Alternatively, as marc_s mentioned, you can use IErrorHandler to map the exception to the fault.
Personally, I create a base Fault class that has a Reason property and I extend all custom faults from this class. When I want to throw the fault, I call:
throw Fault.Create<CustomFault>(new CustomFault("Boo hoo"));
It's also worth noting that I version my fault classes (including the common Fault class) along with all my other services. This is only a concern if service versioning is a concern, though.
Here's the basic Fault class (I've removed argument validation for brevity):
[DataContract(Namespace = XmlVersionNamespace.FaultNamespace)]
public abstract class Fault
{
internal FaultReason Reason { get; set; }
protected Fault(string reasonText)
{
Reason = new FaultReason(new FaultReasonText(reasonText, CultureInfo.CurrentUICulture));
}
public override string ToString()
{
return Reason.ToString();
}
internal static FaultException<TDetail> Create<TDetail>(TDetail fault) where TDetail : Fault
{
return new FaultException<TDetail>(fault, fault.Reason);
}
}
You can design the specific Fault Data Contracts for each of the exception scenario in your WCF service so that you can handle the fault/exception at client side respectively.
try
{
// Actions
}
catch (Exception ex)
{
// Log the exception
// Throw Fault Exception back to client
FaultException fe = new FaultException(ex.Message, new FaultCode("Your fault code"));
//throw fault exception back to WCF client
throw fe;
}
I need to change an existing service API to throw an extra exception for a scenario. The exception will be a subtype of an already thrown exception. Is it okay to do this or will it be considered backwards incompatible?
I have the interface in a separate jar, so if my service throws this new exception which is a child of the already thrown one and the client does not have the new jar, will it break the client or will he be able to still catch the parent exception like before?
The problem is we have a very generic exception that is thrown for every exceptional case and some clients want better ways to identify the exception - apart from parsing the message in the exception, but not all clients may upgrade the interface if we introduce a new exception - how best to handle this scenario?
Thanks
Arvind
As the new exception is a sub-type of an existing one, you shouldn't break any existing code. If the client code traps the base exception it will trap your new one.
You can then refactor the client code to trap the newer more specific exception.
I'm converting code from ASMX to WCF. In my ASMX web services I throw back SOAP exceptions like:
if (ex.InnerException != null)
{
SoapException se = new SoapException(ex.Message, SoapException.ServerFaultCode, Context.Request.Url.AbsoluteUri, ex.InnerException);
throw se;
}
What kind of exceptions should I throw back to WCF clients calling my service? I am guessing the SOAP exceptin is the wrong kind, because the test client doesn't see it as a valid error, and just says - internal error occurred in the web service.
Basically, in a WCF service, you're best off when you only throw FaultException (or FaultException<T>).
This is because of two things: since WCF is designed to be interoperable (your client could easily be a non-.NET app), you should not use .NET exceptions - those are too platform-specific. And two: if you use FaultExceptions (which are translated into SOAP faults), your channel (the connection between client and server) will not be torn down, or "faulted". The WCF runtime on the server side treats all non-handled .NET exceptions as "severe" exceptions and thus puts the channel in a faulted state, assuming something really bad has happened.
If your channel is faulted, you cannot use it anymore - you'll have to close your client proxy and re-create it from scratch.
If you want to (or have to) be very interoperable, you would define your SOAP faults are fault contracts (analogous to data contracts) in a separate file, and then you'd throw FaultException<T> where T would be one of your fault contracts. If you're strictly .NET on either side, you can also stick .NET exceptions into FaultException as generic type T, if you want to - the channel won't be faulted (e.g. you could throw a FaultException<InvalidOperationException> and thus signal back what went wrong).
In WCF you use FaultException. See for example here.