Unhandled exception using FaultException<T> with WCF and WP7 App - c#

I am consuming a WCF service from a WP7 app. Both are in a single VS solution. Everything worked fine until I tried to pass back a FaultException.
When throwing the FaultException from my WCF service, I receive the message "An unhandled exception of type 'System.ServiceModel.FaultException`1' occurred in System.ServiceModel.dll" on the EndInvoke in my proxy. If I hit continue, the exception does not bubble up. My handler code is never hit.
I believe I have everything wired up properly. I've seen plenty of examples, as I've spent an entire day scouring the web for help with this issue. If I stop throwing the FaultException, my application works fine.
In the VS Debug > Exceptions dialog, I have tried disabling FaultException and FaultException'1 under CLR/System.ServiceModel. I have also tried going to Tools > Options, Debuggung > General and turning off "Enable the exception assistant" and "Enable Just My Code (Managed only). None of these has enabled the exception to bubble up to my calling method in the app.
Interface code --
[OperationContract]
[FaultContract(typeof(NotAuthorizedException))]
List<MyResult> GetValues(DateTime beginDate, DateTime endDate);
Exception type --
[DataContract]
public class NotAuthorizedException
{
[DataMember]
public string Message { get; set; }
}
Server code to throw exception --
throw new FaultException<NotAuthorizedException>(
new NotAuthorizedException(),
new FaultReason("Not authorized."),
new FaultCode("Sender"));
Client call to WCF service --
try
{
MyServiceClient myService = new MyServiceClient();
myService.GetValuesCompleted += new EventHandler<GetValuesCompletedEventArgs>(myService_GetValuesCompleted);
myService.GetValuesAsync(DateTime.Now, DateTime.Now.AddMonths(6));
}
catch (FaultException<NotAuthorizedException>)
{
//handle error here
}
Where it breaks (in Reference.cs) --
System.Collections.ObjectModel.ObservableCollection<Namespace.MyService.MyResult> _result = ((System.Collections.ObjectModel.ObservableCollection<Namespace.MyService.MyResult>)(base.EndInvoke("GetValues", _args, result)));
The proxy code is the unaltered code generated from "Add Service Reference" menu item.
It has to be something simple, but I'm just not seeing it!

I believe you should catch the FaultException<NotAuthorizedException>
at myService_GetValuesCompleted instead of where you are doing it now

Related

WCF FaultException inconsistency

I have a WCF service that throws FaultExceptions when something goes wrong. Some of the error classes being thrown works just fine, yet some of the other doesn't work at all and give the following error:
An error occured while receiving the HTTP response to http://localhost/MyService. This could be due to the service endpoint binding not using the HTTP protocol. This could also be due to an HTTP request context being aborted by the server (possibly due to the service shutting down).
With an inner exception saying
The underlying connection was closed: An unexpected error occurred on a receive.
My code works thusly:
Server
public Stream DoSomething() {
if (someCondition) {
if (fileExists) {
return new Stream(); // I know I can't do this, but for example purpose only :)
}
throw new FaultException<System.IO.FileNotFoundException>(new FileNotFoundException());
}
throw new FaultException<MyException>(new MyException());
}
Exception class
public class MyException: Exception
{
}
Client
try {
wcfClient.DoSomething();
} catch (FaultException<FileNotFoundException>) {
// This works just fine
} catch (FaultException<MyException>) {
// This gives the error listed above
}
Both FileNotFoundException and MyException are set up in the contract:
[FaultContract(typeof(FileNotFoundException))]
[FaultContract(typeof(MyException))]
Why does FaultException<FileNotFoundException> work as expected, but not FaultException<MyException>?
If I remove Exception inheritance from MyException everything works as it should (but I want consistency, so I want it to be an actual exception). There is no change if Exception inheritance is left in, but it is decorated with [DataContract].
Why is that? FileNotFoundException inherits from Exception too. One works, the other doesn't. Frustrating!
P.S.: Both the server and the client share the same assembly the interfaces and classes are defined in, so there shouldn't be any contract mismatches.
Your exception should probably be [Serializable]. I think that would solve your problem already.
As a best practice for Exceptions you should also implement the three constructors.

WCF web service call - which exception(s) to catch?

I have a program that calls an external web service, and I want to present the user with a friendly dialog if e.g. the server is down, someone cut the cable etc. Assuming the following code
try {
client.MyWebService()
}
catch(? ex)
{
// display friendly dialog explaining what went wrong
}
what exception(s) should I put in place of the question mark in the code? It is kind of hard to actually test situations like this when everything is working smoothly and I have no control over the external part, so some insight would be appreciated.
Thanks!
The first thing to do is take advantage of the .Faulted event on your proxy, which you can wire up like this:
((ICommunicationObject)client).Faulted += new EventHandler(client_Faulted);
In your client_Faulted event handler you can then try re-connecting, or shifting to a backup server, or disabling the UI, logging the error, or displaying a message there.
It's obviously still good practice to wrap each call in a try-catch as well, but the .Faulted event can let you deal with most channel problems even earlier.
As for the exception itself, you can have your service throw a FaultException that gets passed back to the client with the details you provide. See an example of its use at this blog posting.
You won't get a FaultException if the channel itself fails (FaultException is a way for the server to communicate its own internal faults to the client).
For channel faults, you may get a CommunicationException or TimeoutException.
Finally, take a look at this project on Codeplex for generating Exception Handling WCF proxies. It may give you a more flexible way of handing faults.
It's not really the client's job to provide as much detail as possible. The maximum amount you really have to provide at the client side is as much as you get back in your exception.
var userName = "bob";
try
{
client.MyWebService(userName);
}
catch(Exception ex)
{
//Maybe we know WellKnownExceptions and can provide Foo advice:
if (ex is WellKnownException)
{
Console.WriteLine("WellKnownException encountered, do Foo to fix Bar.");
}
//otherwise, this is the best you can do:
Console.WriteLine(string.Format(
"MyWebService call failed for {0}. Details: {1}", userName, ex));
}
I was asking the same question, as I have to implement some exception handling on web services calls at my client application, so I ended up here. Although it's an old question, I'd like to give my two cents, updating it a little bit.
The answer given by C. Lawrence Wenham was already very good and points to some interesting information, although the blog link is broken and Codeplex is now archived.
I found those articles very valuables:
Sending and Receiving Faults
https://learn.microsoft.com/en-us/dotnet/framework/wcf/sending-and-receiving-faults
Expected Exceptions
https://learn.microsoft.com/en-us/dotnet/framework/wcf/samples/expected-exceptions
And this article from Michèle Leroux Bustamante (apparently the creator of the Exception Handling WCF Proxy Generator CodePlex project) is very insighful also:
An Elegant Exception-Handling Proxy Solution
http://www.itprotoday.com/microsoft-visual-studio/elegant-exception-handling-proxy-solution
I'm still studying the subject but I guess I'll use a lot of ideias from Michèle. I'm just a little bit concerned about using reflection to call the web service's methods, but I wonder if this would have any impact in such kind of operation, that is inherently slow already.
Just to answer here explicitly what was asked originally, which are the exceptions that could be tested against a web service call:
string errorMessage = null;
// A class derived from System.ServiceModel.ClientBase.
MyWebService wcfClient = new MyWebService();
try
{
wcfClient.Open();
wcfClient.MyWebServiceMethod();
}
catch (TimeoutException timeEx)
{
// The service operation timed out.
errorMessage = timeEx.Message;
}
catch (FaultException<ExceptionDetail> declaredFaultEx)
{
// An error on the service, transmitted via declared SOAP
// fault (specified in the contract for an operation).
errorMessage = declaredFaultEx.Detail.Message;
}
catch (FaultException unknownFaultEx)
{
// An error on the service, transmitted via undeclared SOAP
// fault (not specified in the contract for an operation).
errorMessage = unknownFaultEx.Message;
}
catch (CommunicationException commEx)
{
// A communication error in either the service or client application.
errorMessage = commEx.Message;
}
finally
{
if (wcfClient.State == CommunicationState.Faulted)
wcfClient.Abort();
else
wcfClient.Close();
}
As stated by the articles, the order the exceptions are catched is important, since FaultException<TDetail> derives from FaultException, and FaultException derives from CommunicationException.

How to produce an HTTP 403-equivalent WCF Message from an IErrorHandler?

I want to write an IErrorHandler implementation that will handle AuthenticationException instances (a proprietary type), and then in the implementation of ProvideFault provide a traditional Http Response with a status code of 403 as the fault message.
So far I have my first best guess wired into a service, but WCF appears to be ignoring the output message completely, even though the error handler is being called.
At the moment, the code looks like this:
public class AuthWeb403ErrorHandler : IErrorHandler
{
#region IErrorHandler Members
public bool HandleError(Exception error)
{
return error is AuthenticationException;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
//first attempt - just a stab in the dark, really
HttpResponseMessageProperty property = new HttpResponseMessageProperty();
property.SuppressEntityBody = true;
property.StatusCode = System.Net.HttpStatusCode.Forbidden;
property.StatusDescription = "Forbidden";
var m = Message.CreateMessage(version, null);
m.Properties[HttpResponseMessageProperty.Name] = property;
fault = m;
}
#endregion
}
With this in place, I just get the standard WCF html 'The server encountered an error processing the request. See server logs for more details.' - which is what would happen if there was no IErrorHandler. Is this a feature of the behaviours added by WebServiceHost? Or is it because the message I'm building is simply wrong!? I can verify that the event log is indeed not receiving anything.
My current test environment is a WebGet method (both XML and Json) hosted in a service that is created with the WebServiceHostFactory, and Asp.Net compatibility switched off. The service method simply throws the exception in question.
try this:
Returning Error Details from AJAX-Enabled WCF Service
and this
http://zamd.net/2008/07/08/error-handling-with-webhttpbinding-for-ajaxjson/

unhandled exception will make WCF service crash?

I want to know whether unhandled exception will make WCF service crash. I have written the following program which shows unhandled exception in a thread started by WCF service will make the whole WCF service crash.
My question is, I want to confirm whether unhandled exception in threads (started by WCF service) will make WCF crash? My confusion is I think WCF should be stable service which should not crash because of unhandled exception.
I am using VSTS 2008 + C# + .Net 3.5 to develop a self-hosted Windows Service based WCF service.
Here are the related parts of code,
namespace Foo
{
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
[ServiceContract]
public interface IFoo
{
[OperationContract]
string Submit(string request);
}
}
namespace Foo
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
public class FooImpl : IFoo
{
public string Submit(string request)
{
return String.Empty;
}
}
}
namespace Foo
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
ServiceHost host = new ServiceHost(typeof(FooImpl));
protected override void OnStart(string[] args)
{
host.Open();
// start a thread which will throw unhandled exception
Thread t = new Thread(Workerjob);
t.Start();
}
protected override void OnStop()
{
host.Close();
}
public static void Workerjob()
{
Thread.Sleep(5000);
throw new Exception("unhandled");
}
}
}
An unhandled exception on the service side will cause the channel (the connection between the client and the server) to "fault" - e.g. to be torn down.
From that point on, you cannot call from the client using the same proxy client object instance anymore - you'll have to re-create the proxy client.
Your best bet is to handle all error on the server side whenever possible. Check out the IErrorHandler interface, which you should implement on your service implementation class, to turn all unhandled .NET exceptions into either SOAP faults (which will NOT cause the channel to fault), or to report / swallow them entirely.
Marc
Yes, an unhandled exception in a thread will take the process down.
This process will crash:
static void Main(string[] args)
{
Thread t = new Thread(() =>
{
throw new NullReferenceException();
});
t.Start();
Console.ReadKey();
}
This one will not:
static void Main(string[] args)
{
Thread t = new Thread(() =>
{
try
{
throw new NullReferenceException();
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
});
t.Start();
Console.ReadKey();
}
The default behavior of the WCF runtime is to swallow all but a few types exceptions. So if your code throws an exception down the stack to the WCF runtime (such as if you throw from a WCF operation), it will NOT crash the app (unless it is deemed a "fatal" exception, such as OOM, SEHException, etc.). If the exception is not part of the operation's fault contract, then the channel will be faulted, otherwise not.
If the WCF runtime is not under your code on the stack, then the exception /will/ crash the process.
This is similar to the ASP.NET runtime.
If you would like to screen for exceptions flying out of WCF operations in a general way, I recommend using the IOperationInvoker interface. You can also use IErrorHandler, but your IErrorHandler implementation will be notified of exceptions other than those thrown from "user code" (WCF operations), such as SocketAbortedExceptions on WCF internal I/O threads, which are probably not interesting to you.
If you don't handle an exception it gets passed on the operating system and it will respond by killing what ever application caused the exception.
Why don't you just add a try/catch to handle the exceptions so that your service is not killed ?
If you don't have proper error handling it will make the program crash. Its good practise to put a
try{//do something
}
catch{ //handle errors
}
finally{//final clean up
}
block in your code to make sure that if it does throw an exception is to handle it gracefully. examples at http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx
You can make use of FaultException to communicate errors to the client side and keep the logic in the service.
Check this example, hope it helps you.

Proper catching of specific exceptions through web service

I am currently using a C# .NET Service in our client program. As part of the server design, several custom made exceptions are thrown to indicate specific errors (as in any normal desktop program).
The problem is that the Web Service catches these errors and serializes them into a FaultException, with the actual exception (like NoRoomsAvailableException) written in the Message field.
My question is whether there is a best practice for handling these errors. We have just begun working on this, and we would probably do some text pattern matching to pull out the exception type and error message, but it seems like a hacky way to do it, so any "clean" way of doing it would be much appreciated.
The proper way would be to define fault contracts. For example in your web service you could do the following:
[DataContract]
public class NoRoomsAvailableFaultContract
{
[DataMember]
public string Message { get; set; }
}
Next you declare this contract for a given service operation
[ServiceContract]
public interface IMyServiceContract
{
[OperationContract]
[FaultContract(typeof(NoRoomsAvailableFaultContract))]
void MyOperation();
}
And you implement it like so:
public class MyService : IMyServiceContract
{
public void MyOperation()
{
if (somethingWentWrong)
{
var faultContract = new NoRoomsAvailableFaultContract()
{
Message = "ERROR MESSAGE"
};
throw new FaultException<NoRoomsAvailableFaultContract>(faultContract);
}
}
}
In this case the NoRoomsAvailableFaultContract will be exposed in the WSDL and svcutil.exe could generate a proxy class. Then you could catch this exception:
try
{
myServiceProxy.MyOperation();
}
catch (FaultException<NoRoomsAvailableFaultContract> ex)
{
Console.WriteLine(ex.Message);
}
darin has the correct answer. I'll only say explicitly what he implies: web services do not pass exceptions. They return SOAP Faults. If you define your faults properly, as he does, then you get to throw FaultException<fault>. This will become a SOAP Fault with fault in the detail element. In the case of a .NET client, this will then be turned into a FaultException<fault>, which you can catch.
Other platforms may handle this somewhat differently. I've seen IBM's Rational Web Developer generate Java proxy code that creates a separate exception for each declared fault. That was a version before Java generics, so maybe by now it does the same thing as .NET does.

Categories

Resources