I have a windows service, in which I want a top level try-catch that catches any otherwise unhandled (or bubbled) exception, logs it to the Event Log and then swallows it so the service keeps running. However, I can't find any overload to System.Diagnostics.EventLog.WriteEntry that takes an exception as a parameter - is there no way to just give the event log the exception and let it parse out the message on its own?
Unfortunately there is no standard way of just passing the Exception to the Eventlog, built in to the .NET framework.
To have an exception written to the EventLog with the smallest development effort, you would need to write something like:
EventLog myLog = new EventLog();
myLog.Source = "Your Source";
myLog.WriteEntry(exception.ToString(), EventLogEntryType.Error);
But normally you would try to do some formatting of your exception.
Related
It seems catching System.ServiceModel.EndpointNotFoundException doesn't work in orchestrations despite of:
port settings: Delivery Notification = Transmitted (it should work without this in two-way port)
catching exception in specific order
catching Microsoft.XLANGs.BaseTypes.DeliveryFailureException
catching super class exception CommunicationObjectFaultedException like here
scope in scope configuration like here
Orchestration only catches System.Exception. Is that bug or am I missing something?
EDIT :
My configuration:
Sendport WCF-WebHttp
Endpoint REST
I managed to put Microsoft.XLANGs.Core.XlangSoapException catch type by editing odx file in notepad (its hack!)- and This actually works as I want becasue
this type encapsulates System.ServiceModel.EndpointNotFoundException by Biztalk I persume.
This type of exception is thrown in orchesration but VS doesnt let me choose this type of exception I believe that is done in purpose to not to do that.
I am wondering how I can tell camel to redeliver my message based on business logic.
My route is calling a soap endpoint and, depending on the message returned by the server I need to schedule a retry in a few seconds.
Basically, I have this kind of error handling configured :
onException(Throwable.class)
.handled(true)
.processRef("exceptionHandler")
.redeliveryDelay(5000)
.maximumRedeliveries(1)
.to("file://
My exceptionHandler check if the exception is a SOAP Fault, unmarshal it and depending on the content I need to schedule the retry.
Is there anyway of doing that within camel ?
Well, in the end, here is my solution :
from("...")
.doTry()
.to("...")
.doCatch(Exception.class)
.beanRef("handleException")
.end()
.beanRef("handleRegularResponse");
The processor handleException handles the exception, try to understand the issue and then throw a more precise exception. In my case, it can throw 2 types of exception : FunctionalException that do not need to redeliver, and a TechnicalException that I will try to redeliver in a few minutes.
I just have then to declare an error handler for this specific exception :
onException(TechnicalException.class)
.handled(true)
.redeliveryPolicyRef("...")
.useOriginalMessage();
HIH
I'm working on an MVC5 project in VS2013. I seem to be finding that most (but not all) of my exceptions are being ignored by the debugger and as a result I end up with the exception and stack trace simply being written to the browser, precluding any examination of the objects involved in the exception.
For instance - I deliberately code an exception to prove the point:
<Authorize(Roles:="IdentityAdmin")>
Public Async Function Import(model As RegisterViewModel) As Task(Of ActionResult)
Dim a As Object = "he"
Dim b As Integer = a
Clearly the last line will throw a 'type mismatch' exception which I think should result in the debugger halting execution, highlighting the error in the VS2013 UI to enable me to examine the various objects and determine the problem.
Instead I simply find myself with the browser detailing the exception and VS2013 unresponsive:
Server Error in '/' Application.
Input string was not in a correct format.
Description: An unhandled exception occurred during the execution of
the current web request. Please review the stack trace for more
information about the error and where it originated in the code.
Exception Details: System.FormatException: Input string was not in a
correct format.
Source Error:
Line 291: If Db.Users.Find(acct.username) Is Nothing Then
Line 292: Dim a As Object = "he"
Line 293: Dim b As Integer = a
When I insert the same exception-generating code into a non-async part of the code the VS debugger does catch the exception - so I am guessing this is an issue with debugging async code. Is it really the case that the VS debugger can't catch these exceptions?
UPDATE
After further searching I came across a suggestion to disable 'Just My Code' and manually enable various types of exception. There was the expected hailstorm of First Chance Exceptions most of which I could tune out by disabling certain exceptions. But this DID 'fix' the behaviour described above. It seems that the debugger is regarding my child async threads as 'Not My Code'. Slightly baffled but I guess this could be an answer of sorts?
As per the update above, the problematic behaviour detailed in the question seems to be fixed by a combination of:
Turn off 'Just My Code' in the debugger options.
Enable certain classes of exceptions in Debug/Exceptions.. - in my case Common Language Runtime Exceptions and Managed Debugging Assistants seemed to ensure that the debugger caught all my exceptions (async or otherwise).
Disable thrown (but unremarkable) exceptions which cause most grief (wrong globalisation etc).
The last two stages were happened upon somewhat by trial and error and I suspect I should ultimately chase down most of these non-breaking exceptions when I clean the project up.
Disabling Just My Code should not make a difference in this case, enabling "Break when an exception is thrown" is what you want to make the debugger stop at the correct place.
The issue is that when you make the method Async, it runs in a background Task. The Task will catch any exceptions that occur in the code it is executing and re-throw that exception to whatever uses the result of the Task. So for example if you have the following MVC code
Async Function Index() As Task(Of ActionResult)
Dim n as Integer = Await Method1()
Return View()
End Function
Async Function Method1() As Task(Of Integer)
Dim a As Integer = 0
Dim b As Integer = 1 / b
Return b
End Function
The Task executing the code inside of Method1 will catch the exception, and throw it in Index since it is using the result of Method1, then the Task executing Index will catch that exception and re-throw it to the MVC framework code that is using the result of Index, and then the MVC framework handles the exception and displays the error page.
When Just My Code is enabled and methods are executing synchronously the debugger will stop when an exception propagates out of user code with the message that it was "user unhandled". In the case above if an exception propagates from Index to the MVC framework which is not your code, the debugger will stop when JMC is enabled. Since in the case of an asynchronous method the exception is not unhandled but caught by the Task, it does not cross out of user code so disabling Just My code will not make a difference.
The reverse of this is, if an exception occurs in your synchronous method and you have disabled Just My Code, the debugger would not stop anyway, because there is no notion of "User Unhandled" when JMC is disabled and the MVC framework will ultimately handle that exception.
In the EFContextProvider (EF6) SaveChangesCore method, the exception handling looks like this:
} catch (Exception e) {
while (e.InnerException != null) {
e = e.InnerException;
}
throw e;
}
This throws only the most internal exception and hides the relevant information revealed by the external exceptions.
When the SaveChanges process goes through multiple layers the next direct layer exception is lost, and only the last exception in the chain is thrown. It doesn't allow to handle well the exceptions for the caller.
Updated Post
As of Breeze 1.4.6, any .NET Exceptions thrown on the server are now available in their original form in the httpResponse.data property of any async breeze result. Breeze will still drill down to extract a "good" error message, but will no longer obscure the initial exception.
Original Post Below -------------------
It's an interesting point. The reason we did this was because most client side apps aren't written to navigate thru the exception chain and we wanted to expose the most 'relevant' error to the client. Most of the apps we looked at just exposed the client "error.message" property directly and with EF errors this was almost always useless.
However, your point is well taken. I think what we need to do is create a new Exception that has a top level message that is the innermost exception message but still expose the entire exception chain for those that want to drill. I've added an internal feature request for this and will try to get it into a near term release ( probably not the next one because we are already in testing for that one).
And thanks for the input.
Does throwing an exception in a windows service crash the service?
i.e. it will have to be restarted manually
Note:
I am throwing the exception from within the catch clause.
Not strictly so -- it'd only cause problems if the exception is unhandled.
If the exception is uncaught and bubbles back up to the OnStart() method it will crash the service. You will typically see a message in the Windows Event Log similar to the following:
"The MyServiceName Service service terminated unexpectedly. It has done this x time(s).
If you're throwing the exception in Catch, and there's nothing above it to recatch it, then that will cause your service to stop. The OnStart() method needs a try/catch. If you don't want to stop the service when an Exception occurs, then you need to handle it (log it and move on, or whatever).
My preference woudld be to handle expected exceptions, and to have unexpected exceptions either cause the service to stop, or at least stop/restart automatically. If something unexpected happens your service will be running in an unknown state, and who knows what it will do.
We ran into the problem of an untrapped exception on a child thread causing the service to stop without providing any information about what was causing the exception. We used this method to find out the source of the exception.
You can put a Handler to the service to catch all unhandled exceptions (including all sub threads of the service). In VB.NET, you will need to add a handler for AppDomain.CurrentDomain.UnhandledException. It is likely similar in C#. It will then catch anything that does bubble up past your onStart. You can choose to consume it there or allow it to crash the service from there.