WCF Error Logging at Service Boundary - c#

I'm trying to implement an IErrorHandler in my WCF service in order to log every exception that hits the service boundary before it's passed to the client. I already use IErrorHandlers for translating Exceptions to typed FaultExceptions, which has been very useful. According to the MSDN for IErrorHandler.HandleError(), it's also intended to be used for logging at the boundary.
The problem is, the HandleError function isn't guaranteed to be called on the operation thread, so I can't figure out how to get information about what operation triggered the exception. I can get the TargetSite out of the exception itself, but that gives me the interior method instead of the operation. I could also parse through the StackTrace string to figure out where it was thrown, but this seems a little fragile and hokey. Is there any consistent, supported way to get any state information (messages, operationdescription, anything) while in the HandleError function? Or any other ways to automatically log exceptions for service calls?
I'm looking for a solution to implement on production, using my existing logging framework, so SvcTraceViewer won't do it for me.
Thanks.

I ended up putting the logging in IErrorHandler.ProvideFault() instead of IErrorHandler.HandlerError(). The ProvideFault call is made in the operation thread, so I can use OperationContext.Current to get some information to log.

I use the IErrorHanlder in the same way that you describe, but not for logging. Instead on service classes (WCF or not) I use an interceptor as described here. I believe that this technique will capture the information you are interested in.

You could stash any context information you need to log in the Exception's Data dictionary in the ProvideFault method which is called on the operation thread...then reference it in the HandleError method for logging purposes.

Have you used the Service Trace Viewer?

The ProvideFault() operations is being called on the incoming call thread and the client is still blocked waiting for response. I don't think it is good idea to add a lengthy process(like logging) inside this method. That is why they exposed another operation HandleError whch gets called on a separate worker thread.
But I understand your situation. Please share if you found a solution other than logging inside ProvideFault.

What about creating an instance and saving the request message on that instance?

Related

Prevent workflow instance from aborting when exception is raised in a TransactedReceiveScope

We have a sequential WCF workflow service (bidirectional, XAML, IIS-hosted) that performs several calls to other WCF services (that are not necessarily workflows) that execute transactional operations within a TransactedReceiveScope. We've been struggling with an issue that we think is somehow related to the fact that you cannot easily set the value of the AbortInstanceOnTransactionFailure flag like you do with TransactionScope activity.
Whenever an exception is raised in one of the lower layers of our architecture (SOA architecture; we've made a custom implementation of the IErrorHandler interface in order to pass exceptions as they occur across WCF services and have managed to catch them in client applications using regular, C#-style try/catch blocks rather than use fault contracts) and properly catched within either of the custom (derived from CodeActivity activity) transactional activities that comprise the entire transactional scope, the ambient transaction is aborted, hence making the workflow instance abort as well.
What we want to do is bubble up the exception to the client layer (an API layer) and let our marshal do the handling as with the lower layers (deserialize the fault detail and convert it to an exception object), instead of receive a generic "The workflow has been aborted." error message without any further info on it.
Has anyone faced a similar issue or has any idea on what can be done to prevent the workflow from being aborted whenever a transaction is aborted?
We've been looking everywhere for answers and this thread is the only one that comes close to our issue:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/d068c57e-11bf-4e0c-9544-75ede23c329e/how-do-we-make-the-original-exception-bubble-to-the-client-of-a-wcf-workflow-containing-a
Details on the implementation of the exception marshaling:
https://web.archive.org/web/20081118071929/http://www.olegsych.com/2008/07/simplifying-wcf-using-exceptions-as-faults/
It's worth mentioning that the same behavior applies for WCF workflow services using a declarative approach (via *.config files) so that prior implementing transactional activity in our workflows this was working as expected.
Thanks in advance.

Correct way to implement a client-call to a long running server-side method

I am working on SOAP-client in WCF to communicate with a self-hosted WCF service for remote controlling a piece of software that I am developing. This software has a very long running operation (lets call it Print) that will run for several minutes, perhaps up to an hour. I am trying to figure out how to implement the method Print given the following requirements:
The server should be able to raise FaultExceptions to the client, in case something goes wrong.
The client should be informed ASAP should the connection to the service be lost.
The server-side process of Print should continue to run if disconnected, so that the client can reconnect and continue to monitor the process and abort it if necessary.
Since I am new to WCF, I am unsure how to implement this. I currently see two alternatives:
Make Print an async method so that I can "fire and forget" it until it finishes or throws a FaultException. This seems straight-forward, but I see this "problem": There is a client-side request timeout in WCF with default value of 1 minute, which also applies to async methods (if I am not mistaken) and which I would therefore have to increase significantly. This seems a bit like a hack.
Implement the async behavior of Print myself by splitting its behavior into a non-async method StartPringing that starts a server-side task for printing and returns directly (or throws an exception in case something goes wrong) and a client-callback method PrintingFinished. I could then use the callback PrintingFinished to signal to the client, when the print-process has finished or a use an additional callback PrintingFailed to send an exceptions in case something goes wrong. This implementation would be "hidden" behind the async method Print, so that it behaves like any other async method that might throw an exception. Here I see the following challenge: I will have to implement the whole exception callback-stuff myself, to handle exceptions that occur after StartPringing has returned (from StartPringing itself I can throw FaultExceptions).
For both cases I will have to work out how to detect, when the connection is servered (which I am currently doing using a ping method on the service) and then somehow get that event to throw an exception from within the method Print. Implementation-wise this seems more aligned with alternative (2), since I need to already implement all the other event handlers for when the print-process finishes or an exception is thrown. However I am unsure how I would implement this for alternative (1).
So which one of the two alternatives is "better". By better I mean the following considerations:
1. Aligned with the "standard" way in WCF for implementing such a long running method.
2. Maintainability and extensibility.
If I should consider any other alternative, I would be grateful for any other suggestion.
For what I understand of your problem I think if you need a real async communication with reliability to use a message queue like MSMQ. You can use it with WCF : https://msdn.microsoft.com/en-us/library/ms789048(v=vs.110).aspx
Update
In your case, you can use a SOAP call to send print command to the server because it sync and you need to know if the server handle the request. After in the printing operation is long and async. When this operation finish (exception or not) it need to notify client(s). But client could be shutdown for example. For that communication a Message Queue is the solution, MQ ensure that the message will be transmit.
https://en.wikipedia.org/wiki/Message_queue
If you don't want use MSMQ, you can implement a web service on client side to be notified by the printing server, using for example a UUID to match call and notification in a map in memory or in a Data Base.

NServiceBus issue, messages still in queue and handlers are not picking messages

When hitting the endpoint the main method gets invoked but subsequent handlers do not pick messages from queue. The queue keeps building.
Has anyone encountered this issue before?
Thanks,
So far we do not know much about neither your architecture nor your code, we have to guess here. So please bear with me if I say something that may not apply to your case.
Several things come to my mind:
1.) Did you see this tread? NServiceBus Bus.Send().Register(callback) Not Working on IIS/Windows Server 2008
2.) There is some unhandled exception or there is one that gets silently caught and causes your handler method to halt for some reason.
3.) Are you using WCF with NServiceBus? Last week my colleague implemented a WCF service that was hosted with NServiceBus and had a problem that sounds similar to yours. It hit the message handler for the first message, but never handled any subsequent message.
The reason was the handler never returned an enum value as a return code (represented as YourEnum in the code snippet), like it was defined in the service inheritance definition (NServiceBus documentation):
public class YourWcfService : WcfService<YourMessage, YourEnum> { }
The calling service did not need any return values, so my collegue did not return it (I cannot exactly tell why there where no compilation errors, it was not my code...). Therefore the handler method never finished correctly and no other messages could be handled.

How to create an async/background process within a WCF operation?

In my WCF operations I will do the logic necessary for the operation: save a record, get a dataset, etc. and in some cases I need to log the activity as well. However, in these cases I feel that there is no point in having the client application waiting for the WCF operation to log the activity. I would like to fire off the logging process and then immediately return whatever necessary to the client without waiting for the logging process to complete.
I do not care to know when the logging process is complete, just fire and forget.
I also prefer to use BasicHttpBinding to maintain maximum interoperability.
Is this possible? Would anyone care sharing coding samples or links to sites with coding examples?
This can be accomplished pretty easily using any number of threading techniques.
For a very simple example, try modifying this:
// Log something going on.
System.Threading.ThreadPool.QueueUserWorkItem((args) =>
{
System.Diagnostics.EventLog.WriteEntry("my source", "my logging message");
});
Inside that lambda method you can use whatever logging class you prefer, and you can include local variables to the logger if you want to log some current state.

Thread abort exception

I am having an issue in webservice which resides in mono.
I am having a webservice which process huge database operation. I have given "Timeout = 1024" in the "webconfig" file under "appSettings" tag.
When call is done to the webservice after 2 minuter i am getting "thread abort exception".
please help me to overcome this problem
regards
Kumaran
You want to set the request timeout also. This is something like 30 or 60 seconds by default.
In the system.web section, set something like:
<httpRuntime executionTimeout="200"/>
This will affect all the pages, so perhaps you want to put the page in a separate folder so that you can have a local web.config file for this setting.
It is bad practice to place long operations (in your case it is over 2 mins) to synchronous web service method. Usually web service is only facade to start long time method on back-end server or at least another thread. Client can periodcally check if operation is done (so called watchdog pattern). Or review possibility to use oneway method - when client doesn't care about result at all.
By the way, NOTE, even succeed operation in web request must finish with ThreadAbort exception - since HttpRequest contains it raising at end of request processing
Check the innerexception. That's supposed to have some sort of HttpApplication.CancelModelException that should contain a flag indicating if it's a timeout or not. Either way, if you do have an innerexception it may provide more insight.
Additionally, make sure your method is set to async.

Categories