WCF custom fault exception not caught correctly in client - wcf

I'm trying to create some custom FaultException. I've made a DataContract class called CreateFault.
[DataContract]
public class CreateFault
{
private string report;
public CreateFault(string message)
{
this.report = message;
}
[DataMember]
public string Message
{
get { return this.report; }
set { this.report = value; }
}
}
I'm then throwing the fault in a service method.
In IService1.cs
[OperationContract]
[FaultContract(typeof(CreateFault))]
void TestFaultException();
and in Service1.cs
public void TestFaultException()
{
throw new FaultException<CreateFault>(new CreateFault("CreateFault message"), "Message abt exception");
}
I catch the FaultException in my client.
private void btnTest_Click(object sender, RoutedEventArgs e)
{
try
{
ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();
client.TestFaultException();
}
catch (FaultException<CreateFault> ex)
{
MessageBox.Show(ex.Detail.Message, "Success", MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (FaultException ex)
{
MessageBox.Show(ex.Message, "Failure", MessageBoxButton.OK, MessageBoxImage.Error);
}
catch (Exception ex)
{
}
}
Now here comes the problem. When I create a WCF Service Application project in Visual Studio 2010 it works like expected. The error is caught in:
catch (FaultException<CreateFault> ex)
But when I create a WCF Service Library project with my custom FaultExceptions the client does not recognize my custom exception. It instead catches the error in:
catch (FaultException ex)
Why does it not work with WCF Service Application Project?
Edit:
This is what i get during debugging when it catches the exception in
catch (FaultException ex)
(typed ?ex in Immediate window)
{"Message abt exception"}
[System.ServiceModel.FaultException<WpfApplication1.ServiceReference2.CreateFault>]: {"Message abt exception"}
base {System.ServiceModel.CommunicationException}: {"Message abt exception"}
Action: "http://tempuri.org/IService1/TestFaultExceptionCreateFaultFault"
Code: {System.ServiceModel.FaultCode}
Message: "Message abt exception"
Reason: {Message abt exception}
Edit2:
Found the problem. I had two Service references who both had the CreateFault DataContract. And it was using the wrong one when i ran the program.
When i changed to
catch (FaultException<ServiceReference2.CreateFault> ex)
it worked

Found the problem. I had two Service references who both had the CreateFault DataContract. And it was using the wrong one when i ran the program.
When i changed to
catch (FaultException<ServiceReference2.CreateFault> ex)
it worked

Related

Quarkus ExceptionMapper does not handle WebApplicationException

I'm trying to understand if this is a feature or a bug... :-)
For the below controller and exception mapper, for a rest client that will fail with a 401 response, I would expect the exception handler to be invoked for both cases. However it's not invoked for the WebApplicationException. Why is that and how are you meant to register an exception handler for them cases. This is using Quarkus version 0.21.2
#Path("/failable")
public class FailableResource {
#Inject
#RestClient
private SomeHttpClient httpClient;
#GET
#Path("fails")
#Produces(MediaType.TEXT_PLAIN)
public String fails() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
#GET
#Path("works")
#Produces(MediaType.TEXT_PLAIN)
public String works() {
try {
return httpClient.someQuery();
} catch (Exception e) {
e.printStackTrace();
throw new IllegalStateException("Not a WebApplicationException");
}
}
}
And the ExceptionMapper
#Provider
public class HandleMySillyError implements ExceptionMapper<Throwable> {
#Override
public Response toResponse(Throwable e) {
e.printStackTrace();
return Response.ok("Some handled response").build();
}
}
I found out when running in quarkus:dev mode the exception mapper is not invoked. It seems that this is caused by an exception mapper from quarkus that is only used in DEV mode (see https://github.com/quarkusio/quarkus/issues/7883).
I launched my code local as normal a normal java program, causing my exception handler to work as expected. Also when running the code on Openshift, my custom exception mapper is used as well.
note: I used quarkus version 1.8.3

Is ContainerResponseFilter executed if an exception is thrown somewhere in a controller?

I have a RestEasy based service in which I am doing some cleanup work in a ContainerResponseFilter. The problem is that if an unknown runtime exception (i.e. an exception for which I do not have a mapper) is thrown by a resource, the ContainerResponseFilter is never executed.
Is this the expected behavior? Is there a workaround to this? I was looking at the following question (answer by Jonas):
How should I log uncaught exceptions in my RESTful JAX-RS web service?
and that made it seem like the ContainerResponseFilter is executed even when an exception is thrown in the controller?
Am I missing something?
Didn't work for me either. This claims it should work: https://github.com/Graylog2/graylog2-server/issues/1826
I didn't want to investigate further, and simply use a plain old javax.servlet.Filter, but of course there it's hard to set the reponses-headers (after chain.doFilter(), ... grr..
So used a Spring solution:
public static class MyFilter extends OncePerRequestFilter {
#Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
response.setHeader("MyHeader", "MyValue");
filterChain.doFilter(request, response);
}
}
Base on the source code of SynchronousDispatcher in RestEasy.
protected void writeResponse(HttpRequest request, HttpResponse response, Response jaxrsResponse) {
try {
ServerResponseWriter.writeNomapResponse((BuiltResponse)jaxrsResponse, request, response, this.providerFactory);
} catch (Exception var5) {
this.writeException(request, response, var5);
}
}
public void writeException(HttpRequest request, HttpResponse response, Throwable e) {
if (response.isCommitted()) {
throw new UnhandledException("Response is committed, can't handle exception", e);
} else {
Response handledResponse = (new ExceptionHandler(this.providerFactory, this.unwrappedExceptions)).handleException(request, e);
if (handledResponse == null) {
throw new UnhandledException(e);
} else {
try {
ServerResponseWriter.writeNomapResponse((BuiltResponse)handledResponse, request, response, this.providerFactory);
} catch (Exception var6) {
throw new UnhandledException(var6);
}
}
}
}
ContainerResponseFilter will not execute.
If you want to set headers when exceptions happen, you need an exception handler to deal with it.

Exception handling on Tasks without Wait()

What is the best approach to handle exception of a Task that does not Wait()? I read a couple of blogs which spoke about using ContinueWith because regular try/catch cannot handle Task exception. Below code does not validate that.
Method 1:
public class Service1 : IService1
{
public string GetData(int value)
{
var a = Task.Factory.StartNew(ThrowException);
return string.Format("You entered: {0}", value);
}
private void ThrowException()
{
try
{
Thread.Sleep(6000);
throw new ArgumentException("Hello from exception");
}
catch (Exception)
{
Trace.WriteLine("Log it");
}
}
}
Method 2:
public class Service1 : IService1
{
public string GetData(int value)
{
var a = Task.Factory.StartNew(ThrowException);
a.ContinueWith(c => { Trace.WriteLine("Log it"); },
TaskContinuationOptions.OnlyOnFaulted);
return string.Format("You entered: {0}", value);
}
private void ThrowException()
{
Thread.Sleep(6000);
throw new ArgumentException("Hello from exception");
}
}
Are Method 1 and Method 2 doing the same thing? Is there a better way to implement this.
Edit: Added code snippet for continuewith.
Both methods work and they are equivalent. Choose what you like most. The continuation based one has the advantage that you can make the error handling into an extension method (or some other central helper).
Are you aware that IIS worker processes can suddenly disappear for many reasons? In that case background work is lost. Or, the work faults but the error handler disappears.
It looks like it will work if all you need is to call methods on the Trace class. However, if you need custom exception handling, I would recommend injecting an exception handler:
private void ThrowException(Action<Exception> handleExceptionDelegate)
{
try
{
// do stuff that may throw an exception
}
catch (Exception ex)
{
if (handler != null)
handleExceptionDelegate(ex);
}
}
Then you could do
Task.Factory.StartNew(() =>
{
ThrowException((ex) =>
{
// Handle Exception
});
});

FaultException and Details

I am working on WCF Services from Couple of Days. I had a written a service with an Exception as
public String Login(string Vendorname, string VendorAccessCode)
{
try
{
if()
{
}
else
{
UserIdentityToken = string.Empty;
this.ErrorMessage = "Authentication failed. Please contact administrator";
throw new FaultException(this.ErrorMessage);
}
}
catch (FaultException ex)
{
logger.Error(ex.Message);
}
catch (Exception ex)
{
logger.Error(ex.Message);
}
return UserIdentityToken;
}
After this i am handling the exceptions in client side in a Messgae Inspector as
public class MessageInspector : IClientMessageInspector
{
public void AfterReceiveReply(ref Message reply, object correlationState)
{
if (reply.IsFault)
{
MessageFault fault = MessageFault.CreateFault(new FaultCode("Receiver"), new FaultReason(reply.ToString()));
throw new FaultException(fault);
}
}
}
I am handling my Client Side Code as
try
{ objVendorServiceClient.Login(txtuserName.Text.Trim(),
txtAccessCode.Text.Trim());
}
catch (FaultException ex)
{
lblAuthenticationMessage.Text = ex.Message;
throw ex;
}
But when ever the authentication fails in Service, the Reply.IsFault is returning false only. could any one explain me what is reply.Isfault and how exactly it is useful to me?
Message.IsFault Property:
Gets a value that indicates whether this message generates any SOAP faults.
You say:
when ever the authentication fails in Service, the Reply.IsFault is returning false
That is because you catch the fault yourself, log it, and then return an empty string. You'll have to throw the FaultException in order for WCF to catch it and create a SOAP fault from it.

WCF: how to bubble exception from service to client with asyn methods

I am trying to catch an exception in a method of the service and bubble this exception to the client.
My code is:
CONTRACT:
[OperationContract(AsyncPattern = true)]
[FaultContractAttribute(typeof(Exception))]
IAsyncResult BeginUpdateUsers(List<Users> paramUsers, AsyncCallback callback, object state);
List<Users> EndUpdateUsers(IAsyncResult result);
IMPLEMENTATION INTERFACE
public IAsyncResult BeginUpdateUsers(List<Users> paramUsers, AsyncCallback callback, object state)
{
Task<List<Users>> task= Task<List<Users>>.Factory.StartNew(p => aupdateUsersMethod(paramUsers), state);
return task.ContinueWith(res => callback(task));
}
public List<Users> EndUpdateUsers(IAsyncResult result)
{
try
{
return ((Task<List<Users>>)result).Result;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private updateUsersMethod(List<Users> paramUsers)
{
try
{
}
catch(Exception ex)
{
throw new Exception(ex.Message);
}
}
I get an error in runtime in the catch of the method updateUsersMethod. It enters in the catch, but in the line when I throw new Exception, I get the following error: the usr's code does not control the exception.
EDIT1: I solved the problem, I must throw FaultException instead of the Exception. However, the exception dos not arrive to the client. which could be the reason?
EDIT2: Well, I must to use faultException, but I am having the same problem, it says me that the faultException is not handle by the user's code. I have try/catch in all the methods, Begin, End and the auxiliar method updateUsersMethod.