I am just learning WCF and wrote a Windows Service hosting a WCF service. Ever since I started it in service.msc in the remote server (physically remote, and very slow) I think I have already hit and fixed like a hundred errors here and there already. I am now finally stuck.
At this point, I have enabled tracing and message logging. The first and only function call looks like this:
[OperationContract]
public MyServiceResponse ConnectToAXDynamicsViaDotNET2BusinessConnectorWithSadFace()
{
try
{
throw new NotImplemented();
}
catch(Exception ex)
{
return new MyServiceResponse(ex, ex.Message);
}
}
[DataContract]
public class MyServiceResponse
{
// ...
}
Upon calling the operation, the client just sits and waits until timeout. Checking the trace, it records my thrown exception. So it makes me wonder if WCF actually blocks there and ignore my catch clause.
I then tested with just a simple return value without throwing and it FINALLY works.
My question is, how then can I make the above scenario work, ie. catch the exception and return a sensible result back to client? Maybe it's just the tracing that blocks me, but I want to enable tracing during this whole debugging process otherwise it's really hard to work.
Thanks for your precious help!
EDIT: Sorry, I found this right after I posted this question. Happens all the time: http://msdn.microsoft.com/en-us/library/ee942778.aspx but I have yet to read it as I got to run off now. Not sure it it will solve my problem.
Risk being downvoted, but just for documentation sake and general usefulness of having this question:
Through reading the FaultException handling articles, I guess the above behavior is due to Exception class not serializable. And the service silently disconnects itself without returning any error messages eventhough the "send (unknown) faults to client" is enabled. As for why it does so, I have no idea yet. Will update if I find out more.
I have since changed to throw new FaultException() instead of returning my own MyServiceResponses.
Related
I'm trying to disable retries for some specific exceptions completely.
I know that in my code - when I'm trying to handle message X and if the handler throw a "ZZZ" type exception, I'm sure there's no way any number of retries would help;
What I want to do is send that message directly to error queue immediately without any retries.
How can i do that ?
I know you've already accepted an answer, but since you are trying to circumvent the plumbing builtin for a very specific scenario, you could handle the message in a try/catch and either send the message directly to the error queue or let the FLR/SLR handle it.
Please note, this is not an ideal scenario. In most cases, it is actively discouraged to handle the error handling of messages and instead allow the infrastructure to manage it.
Here's a possible implementation:
public void Handle(SomeCommand message)
{
try
{
//Do thing that might throw exception
}
catch (SpecificException ex)
{
_bus.Send(new Address("errorQueue", "machine"), message);
}
catch (Exception ex)
{
throw ex;
}
}
EDIT I'm promoting Marcin's comment to be included in this answer so it isn't missed:
Please bear in mind that by using this approach without setting
appropriate message headers you will lose the ability to return these
failed messages to the source queue. Please take a look at this doco
for details: http://docs.particular.net/nservicebus/messaging/headers#retries-handling-headers. – Marcin
Hoppe
You can't for the first level retries, only for the second level retries. I personally wouldn't worry about it (I have something similar, where certain exceptions I know that it won't be fixed). There's generally no downside to letting them go in the FLR.
I have an interesting use case where certain exception types mean "This message is no longer valid and should be ignored" but this code doesn't have any awareness of the Bus in order to call Bus.DoNotContinueDispatchingCurrentMessageToHandlers().
I loathe boilerplate code like try/catch blocks that need to be present in every single message handler. So I started implementing a UnitOfWork to handle and swallow the exception, but I can't find a way to tell the framework that "Yes, this code generated an exception, but forget about that and just complete the transaction."
Bus.DoNotContinueDispatchingCurrentMessageToHandlers() does not work. I tried having an ITransport injected and calling AbortHandlingCurrentMessage() but that caused the entire universe to blow up. Even stepping through the source code I seem to be at a loss.
Note that it very well may be that this is a horrible idea, because faking that there is no exception when there is in fact an exceptional case would cause the transaction to commit, causing who knows how many bad unknown side effects. So it would be preferable to have a method that still rolls back the transaction but discards the message. But I would be interested in a potential "Yes I know what I'm doing, commit the transaction regardless of the exception" option as well.
As of NServiceBus version 4.4 you can control this by injecting a behavior into our handler pipeline.
This let's you control which exceptions to mute.
class MyExceptionFilteringBehavior : IBehavior<HandlerInvocationContext>
{
public void Invoke(HandlerInvocationContext context, Action next)
{
try
{
//invoke the handler/rest of the pipeline
next();
}
//catch specific exceptions or
catch (Exception ex)
{
//modify this to your liking
if (ex.Message == "Lets filter on this text")
return;
throw;
}
}
There are several samples of how this works:
http://docs.particular.net/samples/pipeline/
That said I totally agree with Ramon that this trick should only be used if you can't change to design to avoid this.
A dirty solution would be having a unit of work test the exception, put the message id in a shared 'ignore' bag (concurrent dictionary in memory, db, what works for you) , let it fail so that everything is rolled back, in the retry have a generic message handler compare the message ID and let that call Bus.DoNotContinueDispatchingCurrentMessageToHandlers()
If you do not want to work with a unit of work then you could try to use the AppDomain.FirstChanceException.
I wouldn't advice any of these as good solution :-)
Why would you like to 'swallow' unhandled exceptions?
If you want to ignore an exception then you should catch these in the handler and then just return and log this.
What I'm more interested in is what about state? You maybe have already writen to a store. Shouldn't these writes be rolled back? If you swallow an exception the transaction commits.
It seems to me you are running in a kind of 'at least once delivery' environment. THen you need to store some kind of message id somewhere.
Or is it an action initiated by several actors based on a stale state? In that case you need to have first/last write wins construction that just ignores a command based on a stale item.
If you handl an event then swallowing a exception seems not correct. They usually say that you can ignore commands but that you always have to handle events.
Shouldn't this be part of validation? If you validate a command then you can decide to ignore it.
I'm currently building a WP7 app that consumes WCF Data Services hosted on a web server. What I'd like to deal with is
cathayService.ServiceException += (sender, e) =>
{
Debug.WriteLine(e.Exception.ToString());
MessageBox.Show(e.Exception.ToString(), "Service Error", MessageBoxButton.OK);
};
The service exception triggers if I have a lack of internet connectivity. It also triggers when I face with fast app switching. How'd I be able to differentiate the source of the ServiceException?
Hope someone can give me an idea... Many thanks! :)
[It's unclear if you are getting a ServiceException instance, or if you are referring to the ServiceException event in some places above]
Check the exception you get - if it's typed as ThreadAbortException, that means you are being switched out. If you actually get a ServiceException thrown, check it's inner Exception and see if THAT guy is ThreadAbortException.
My suggestion is that you don't hook that event though and instead use the actual callback events on the WCF client to check the .Error property of the EventArgs you get back.
I'm running two glassfish v2 domains containing stateless session EJBs. In a few cases, an EJB in one domain has to call one in the other.
My problem is that when the called EJB aborts with an exception, the caller does not receive the message of the exception and instead reports an internal error that is not helpful at all in diagnosing the problem. What happens seems to be this:
At the transport layer, a org.omg.CORBA.portable.ApplicationException is created,which already loses all detail information about the exception except its class.
Inside com.sun.jts.CosTransactions.TopCoordinator.get_txcontext(), the status of the transaction ass rolled back causes a org.omg.CosTransactions.Unavailable to be thrown, which gets wrapped and passed around a few times and eventually results into this error being displayed to the user:
org.omg.CORBA.INVALID_TRANSACTION: vmcid: 0x0 minor code: 0 completed: No
at com.sun.jts.CosTransactions.CurrentTransaction.sendingRequest(CurrentTransaction.java:807)
at com.sun.jts.CosTransactions.SenderReceiver.sending_request(SenderReceiver.java:139)
at com.sun.jts.pi.InterceptorImpl.send_request(InterceptorImpl.java:344)
at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeClientInterceptorStartingPoint(InterceptorInvoker.java:271)
at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeClientPIStartingPoint(PIHandlerImpl.java:348)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(CorbaClientRequestDispatcherImpl.java:284)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.request(CorbaClientDelegateImpl.java:184)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:186)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)
Is there anything I can do here to preserve information about the actual cause of the problem?
The cause of the problem should be available in the server log of the domains hosting the EJB that had a problem.
It sounds like getting more info back from the other end may be difficult... I do not know which issue tracker would be the right one for the info lost when the ApplicationException is created/thrown.
A total hack would be to create a set of custom exception classes in the project that has the ejb that has failed. You would make them very fine grained to cover the likely causes of the problem and provide enough detail in their name to identify the actual location of the problem, too. Yucky... but that may be the only choice until an issue gets filed and the fix is distributed.
Is there anything I can do here to
preserve information about the actual
cause of the problem?
Unfortunately, no. The ORB does not use normal object serialization for system exceptions (i.e., org.omg.CORBA.*), which means that causes are lost. As #vkraemer said, you'll need to rely on server logs.
I finally got to the bottom of this: actually, Glassfish transmits exceptions through IIOP quite correctly and everything works as it should... unless you do something idiotic like this:
try{
ejb.getFoo();
}catch (Exception e){
// try again
ejb.getFoo();
}
Yeah, it was our own damn code that swallowed the exception and tried to call a transaction-requiring EJB method within a distributed transaction that's been rolled back due to the exception.
just a general question,
do you ALWAYS have to handle error?
i was just having this debate with one of my coworker where in his code I see a lot places where stuff are wrapped around a try statement and in the catch statement there is nothing.
I always thought it is a bad practice to not handling error or hide them from the user (except log them in the log file).
just want to know what other people thinks
thanks.
If you can't handle the exception, then don't catch it. It may be that someone further up the call stack can properly handle it, and congratulations, you've now prevented them from doing their job <golfclap/>.
The practice of catching an exception and then "silencing it" is EVIL! i think 99.99% of all SOers will agree on that one.
Here's a very nice article from CodeProject on exception handling best practices. Guess what one of the sections is devoted to?
The worst thing you can do is catch (Exception) and put an empty code block on it. Never do this.
Any exception handling article worth its salt will mention the exception swallowing concept, and not to do it, in some way.
Only a Sith deals in absolutes. Seriously, though, I can think of at least one instance we ran across just recently where it was desirable to just drop it and move on. We recently implemented an in-house click tracking solution that sends an async AJAX request to an MVC controller to be logged. We don't care if it does not get logged and we don't want our own logs filling up with error logs that we don't want. so why bother with the overhead of doing anything in the catch block. We considered adding code in the catch block to at least increment a counter when we got an error, but there was no business reason for it at this time.
It really comes down to whether you are doing it out of laziness or because there is actually a good reason not to.
I'll probably get flack for saying that as it is bad practice in general. Do I get points for bravery?
You have to handle the exception if there is something you can do with it
try
{
//CODE
}
catch
{
LogException();
//and/or
RollbackTransaction();
//and/or
ShowFriendlyMessageToUser();
//and/or
DoSomethingUsefullWithTheException();
throw; //This is optional
}
This make no sense, but I've seen it a lot
try
{
//CODE
}
catch
{
throw;
}
EDIT 1
And you need a very good argument to put something like this. And probably you'll get fired anyway :-p
try
{
//CODE
}
catch
{
//HIDE TO THE WORLD THAT THIS IS FAILING
}