I'm using IDispatchMessageInspector to inspect request/response messages in my WCF service and log some data to our logging database. I also have a custom error handler which catches exceptions and transforms them to faults. I'd like to be able to log the exception (if any) in the IDispatchMessageInspector.BeforeSendReply() method but I cannot figure out how to capture exception data. Is there a fault collection of some sort that I should be looking for? I realize I could log the exception in the IErrorHandler.HandleError() method, but I'd like to include the exception details along with the other details that I'm capturing while inspecting the request/response messages. Thanks!
Here's something I wrote a while ago about this topic. Basically, an exception will cause a fault message to be sent to the client as a reply
Related
What exceptions which should be handled in application would MassTransit throw?
I am using MassTransit with RabbitMQ.
I am wondering what exceptions we should catch from MassTransit.
Do you have anything like API document. (Hope it describe about errors)
Here is a list of exceptions that MassTransit may throw:
MassTransit.MessageData.DecodeException: Thrown when the message body cannot be decoded.
MassTransit.MessageData.EncodingException: Thrown when the message body cannot be encoded.
MassTransit.MessageData.MissingContentTypeException: Thrown when the message does not have a content type.
MassTransit.MessageData.NotFoundException: Thrown when the message cannot be found in the message data store.
MassTransit.MessageData.OptimisticConcurrencyException: Thrown when the message data has been modified since it was last read.
MassTransit.MessageData.StoreException: Thrown when an error occurs while storing or retrieving the message data.
MassTransit.MessageData.TooLargeException: Thrown when the message size exceeds the maximum allowed size.
MassTransit.Pipeline.Filters.CircuitBreakerException: Thrown when the circuit breaker is open.
MassTransit.Pipeline.Filters.ConcurrencyException: Thrown when the filter concurrency limit is reached.
MassTransit.Pipeline.Filters.RetryException: Thrown when the filter retry limit is reached.
Note that this is not an exhaustive list and there may be other exceptions thrown by MassTransit depending on your specific implementation.
I would recommend reviewing the code and seeing if more exceptions have been added, and review if you need to catch them.
Remember exceptions are not Pokemon, you don't have to catch them all :)
https://github.com/MassTransit/MassTransit/search?q=throw&type=commits
I understand NServiceBus's retry mechanism to be primarily for connectivity problems or database deadlock problems, which is great and I love it for that.
However, I would like to configure NServiceBus' retry mechanism to not bother with a retry if the exception is typeof(ApplicationException). My code throws this kind of exception when there is a broken business rule (like a customer on hold), so no matter how many times this message is retried by NServiceBus' quick-retry mechanism, it will fail. This scenario requires that users take action on the data and then use ServiceInsight to re-queue the message for processing.
Can this be done?
I would reconsider using your application logic to inform users about this type of errors using Reply or Return in your handler, that should be located in the catch (ApplicationException) section. Then users change the data and send the message again using your application, not ServiceInsight. In this case, do not re-throw the ApplicationException in your catch block and this will prevent NServiceBus from retrying your message handling.
I created a WCF service and the user requirement is to have only one client connected on the service at a time.
So I set the value of the parameter maxConcurrentSessions to 1.
It's working great and if another client try to connect after a specific time it receives a timeout exception error.
But I don't like to send the timeout exception error to the client I want to have a more specific error like :
A timeout occurs because the number of maximum client on the service was reached.
Something like that.
It's there a way to do that?
Thanks
You can override default exceptions by implementing IErrorHandler
From MSDN
To explicitly control the behavior of the application when an
exception is thrown, implement the IErrorHandler interface and add it
to the ErrorHandlers property. IErrorHandler enables you to explicitly
control the SOAP fault generated, decide whether to send it back to
the client, and perform associated tasks, such as logging. Error
handlers are called in the order in which they were added to the
ErrorHandlers property.
Implement the ProvideFault method to control the fault message that is
returned to the client
Also check this one .Net WFC/Web service exception handling design pattern
I have a Workflow Service that has a few receives that listen to MSMQ queues. I would like to implement the following behavior:
If a correlation exception occurs (ie - workflow instance is gone), throw away the message.
If an InstanceLockException occurs (ie - this workflow instance is doing something on another server), put the message in the retry queue.
I have tried putting TransactedReceiveScope around the Receive activities, but it will put the message in the retry queue on a correlation error. Plus, it causes a lot of problems under heavy load.
Without the TransactedReceiveScope, the message is thrown away if there is an InstanceLockException.
Is there a way to implement this behavior (maybe via behavior extensions)?
You can implement a IErrorHandler for WCF to catch all unhandled exceptions whether thrown by your app or by WCF. The thing you have to be careful about with the netMsmqBinding is that throwing a fault in this handler means the message has been "successfully" processed and it will taken off the queue. In your case when InstanceLockException occurs, you'll have to let it remain unhandled if you want the built-in MSMQ 4 retry handling to occur. You'll also need to allow the PoisonMessageException to remain unhandled for proper MSMQ retrying to occur.
I'm not familiar with using Workflow, but knowing how MSMQ and WCF work you could try this
When a CorrelationException occurs:
Catch the exception
Return from your service method
Since your service method doesn't throw an exception it will think the message was successfully processed and remove it from the queue.
When a InstanceLockException occurs:
Catch the exception
rethrow the exception
Since your service method throws and exception it will think the message was not successfully processed and move it to the retry queue.
I think you'll have to create a WCF custom behavior to catch those exceptions.
I have the standard error handing in place in my service:
I have an IErrorHandler hooked to the service to handle unexpected errors during service execution.
I have try/catch blocks in all my service methods to handle expected cases.
However, there are cases where exceptions are thrown on the server and neither is called.
Here is a case where the server exception is not sent to the IErrorHandler:
Set the receiveTimout on the server binding to 5 seconds.
On the client do this:
.
Service1Client sc = new Service1Client();
ICommunicationObject o = sc as ICommunicationObject;
o.Open(); // open channel
sc.GetData(10); // do a first call
Thread.Sleep(10000); // wait longer than the server receiveTimeout
sc.GetData(10); // Attempt another call: server throws a FaulException
In that case, the error is thrown on the server but I cannot find a way to handle it (and log it). I know an error is raised because if I attach a debugger on the server process and break on all exceptions, the debugger breaks.
I have found other similar cases where low level errors are not passed to my program.
Where can I hook my code to ensure that I can handle ALL exceptions that occur on the server before they are returned to the client app? Should I implement my own IChannel or some other low level interface?
Thanks
UPDATE Sep 21 2009: See this thread on the Microsoft WCF Forum. I'll probably have to implement my own Channel if I want to handle this type of exception. I'll update this post again when I have more info.
After much research and experimentation, the answer is:
At this time (.Net 3.5) there is no mechanism that allows one to handle all possible exceptions that may occur in the context of a WCF call.
Exceptions that happen during the service method execution can easily be handled with:
Try/catch blocks in all service methods to handle expected cases.
IErrorHandler hooked to the services to handle unexpected errors during service execution.
However, for low level WCF infrastructure errors, there is no perfect solution. The best solution that exists seems to be to implement a custom channel to catch more exceptions.
In this Microsoft Connect Bug Report, Microsoft confirms that there is no way to handle all types WCF infrastructure errors.
In this thread on the Microsoft WCF forums, there is a sample on how to implement a custom channel. That solution only works for HTTP, not for HTTPS. Also some WCF infrastructure errors are not caught by the custom channel either (see more details in that specific thread).
Use FaultContracts. Then the fault can be handled at the client end.
http://msdn.microsoft.com/en-us/library/ms732013.aspx
http://www.c-sharpcorner.com/UploadFile/ankithakur/ExceptionHandlingWCF12282007072617AM/ExceptionHandlingWCF.aspx
This is also much better for debugging, since often you will be developing a client and don't want to bring down the server for debugging purposes.
On the client end, use try/catch blocks to catch all exceptions/faults. There are definitely errors that can't be detected on the server end, such as a communication problem, so you need to handle errors on the client end anyways.
If you want centralized error handling, you can create a service that takes messages about all errors, send the error to that server, and have it log that. This can be useful if you want to create a centralized message tracing/performance analysis/logging tool and have a large number of application processors, servers, clients etc.
The point is - if the server is not reachable or can't handle the message, there won't be an error on the server - the error will pop up on the client ("TimeoutException" or others).
So in those cases, having the IErrorHandler on the server really isn't gonna help - since the error really happens on the client (no connection can be made, due to network down, or typo in server's address or sstuff like that).
So on the client side, you definitely also have to use try....catch around all your server calls.
Marc
Set up diagnostic tracing and check the logs with Service Trace Viewer Tool. Link contains information about configuring tracing as well.