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.
Related
I'm just using NewRelic error trapping for my coldbox application. From OnException method, I'm just sending the error struct to log the error.
My code in onexception method
public function onException(event,rc,prc){
NewRelic.logError( prc.exception.getExceptionStruct());
}
The logerror() method resides in NewRelic.cfc and contains the following code
public boolean function logError(
required struct exception
) {
var cause = arguments.exception;
var params = {
error_id = createUUID(),
type: arguments.exception.type,
message: arguments.exception.message
};
writeDump(this.newRelic);
this.newRelic.noticeError(cause, params);abort;
return true;
}
So while error, I'm gettig the following error.
The noticeError method was not found.
You can see that, the noticeError() method is there in the object, but it is overloaded with arguments.
I'm using the same code for NewRelic error trapping in another coldfusion project without any frameworks.
Calling error.cfm through Cferror tag, and the code in error.cfm as follows
<cfset Application.newRelic.logError( variables.error )>
And in NewRelic.cfc, the logerror() method contains the same code as in the coldbox application. But it is logging errors in NewRelic without any issues.
This is the method I need to notice errors and log it in NewRelic.
noticeError(java.lang.Throwable, java.util.Map)
So I just thought to get the classname of the first argument Cause through the following code from both applications within logError() in NewRelic.cfc, to get the difference.
writeDump(cause.getClass().getName());
I'm getting
coldfusion.runtime.ExceptionScope for Coldbox application
and
coldfusion.runtime.UndefinedVariableException for normal coldfusion application
The cause argument is not throwable from coldbox application. So how to get the original error struct from coldbox application? and make it throwable to fix the noticeError method was not found issue.
The change in the underlying class happens when ColdBox duplicates the error object with CFML's duplicate() method. I doubt that ColdFusion behavior is documented anywhere, but I don't see an easy way to get around it right now other than creating your own instance of a java.langException and populating it with the details of the original error.
If you want to modify the ColdBox core code, this happens here:
https://github.com/ColdBox/coldbox-platform/blob/master/system/web/context/ExceptionBean.cfc#L43
I have entered this ticket for the ColdBox framework for us to review if we can stop duplicating the error object in future versions of the framework.
https://ortussolutions.atlassian.net/browse/COLDBOX-476
Update: Adam Cameron pointed out this ticket in the Adobe bug tracker that details this behavior in the engine. It was closed as "neverFix".
https://bugbase.adobe.com/index.cfm?event=bug&id=3976478
In Lablgtk, whenever there is an exception in a callback, the exception is automatically caught and an error message is printed in the console, such as:
(prog:12345) LablGTK-CRITICAL **: gtk_tree_model_foreach_func:
callback raised an exception
This gives no stack trace and no details about the exception, and because it is caught I cannot retrieve this information myself.
Can I enable more detailed logging information for this case? Or prevent the exception from being caught automatically?
I guess the best way to do so is to catch your exception manually and handle it yourself.
let callback_print_exn f () =
try f () with
e -> my_exn_printer e
Assuming val my_exn_printer : exn -> unit is your custom exception printer, you can simply print your callbacks exceptions by replacing ~callback:f by ~callback:(callback_print_exn f) in your code.
Of course, you can also with that method send that exception to another
thread, register a "callback id" that would be passed along with your exception...
About the stack trace, I'm not sure you can retrieve it easily. As it's launched as a callback, you probably want to know the signal used and that can be stored in your callback handler.
I had another similar issue, but this time it was harder to find where to put the calls to intercept the exception.
Fortunately, this time there was a very specific error message coming from the Glib C code:
GLib-CRITICAL **: Source ID ... was not found when attempting to remove it`
Stack Overflow + grep led me to the actual C function, but I could not find which of the several Lablgtk functions bound to this code was the culprit.
So I downloaded the Glib source, added an explicit segmentation fault to the code, compiled it and used LD_LIBRARY_PATH to force my modified Glib version to be loaded.
Then I ran the OCaml binary with gdb, and I got my stack trace, with the precise line number where the Lablgtk function was being called. And from there it was a quick 3-line patch.
Hacks like this one (which was still faster than trying to find where to intercept the call) could be avoided by having a "strict mode" preventing exceptions from being automatically caught. I still believe such a switch should be available for Lablgtk users, and hope it will eventually be available.
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.
From what I understand throw causes an exception.
It looks like it can be used to test your catch exception.
What are the benefits/uses for it? Why would you want to purposely cause an exception?
Why use throw in catch? Seems like it catches the exception just to cause an exception again.
try
{
//blah
}
catch
{
throw;
}
throw; rethrows the current exception. It's used for when you want to catch an exception and do some handling of your own, but otherwise still want the exception to propagate more-or-less as if you never caught it.
The difference (in languages that let you just say throw;, like C#) is that when you rethrow an exception, the original stack trace remains mostly intact. (It includes the line where you rethrew the exception rather than the line where the exception occurred in the corresponding try block, but otherwise the whole stack trace is preserved.) If you say throw the_exception_you_caught;, it's usually treated as if you threw a brand new exception from right there -- the existing stack trace gets obliterated and a new one starts from that point.
Exceptions are mechanism for error handling. For instance, you may throw an exception to indicate that a webservice call has timed out, or bad input as been provided to a method. The idea is that calling code knows how to deal with these exceptions and handles them gracefully — perhaps fixing what's wrong in the case of bad input (by prompting the user) or by trying a callout a second time.
A catch block is where you do your handling of the error, and in certain scenarios you may want to do some local cleanup in the method running, but then you still need to report the error to calling methods, so you throw the exception once more (or throw a different, maybe more generic or specific exception) which you then handle in your calling code.
Description
You can do this to, for example, log something and give the exception back to the calling method / assembly.
You can handle the exception and signals the caller that a exception is happend instead of return a boolean that indicates if the method has success.
This is useful for unit tests and more.
Sample
try
{
//blah
}
catch
{
// log exception to textfile of database
throw;
}
This is a common pattern in .Net code. It's used when the caller wants to either log, wrap or react to an exception and then pass it back up to the caller. For example
try {
SomeFunction();
} catch {
CloseMyResource();
throw;
}
The advantage of throw vs throw exceptionVariable is that throw preserves the original stack trace. The next person to catch the exception sees the original stack trace. This is essentially for tracking down errors in deep call stacks.
I think it may be better to think of a throw as your informed reaction to an exception in your code rather than the cause. Semantics I know but it helps.
You throw a different exception in a catch to add information. Your converting what may be a generic OS exception into one meaningful to your application. e.g. Out of memory exception may be caught and a new exception with the out of memory as the inner exception be throw saying something like "Error while computing the answer to life the universe and everything". More useful that just an out of memory exception.
You may use a 'throw' on its own as a rethrow. The catch allows you to do something before rethrowing. If we are talking C# check out 'finally'.
When something really bad happens, that ought not happen, then you can abort and inform the caller by throwing an exception. It means that you do not need to have every method returning result codes and every caller testing fault/success codes. It also nicely abstracts who handles such 'exceptions' or even if you just leave it to the OS.
Quick answer ... it makes your code simpler and gives you better control of aborting and handling exceptions. Think of it as a messaging/abort system.
You would re-throw the same exception if you wanted to do some logging here or some clean up but would like to still have the calling functions further up the call stack to have to handle that same exception.
A more typical use would be:
try {
// ...
} catch (EmailException ex) {
SMS.AlertError("Email is not working", ex);
throw;
}
If you throw ex you will have stripped out information such as the call stack from the exception.
The some function above that would:
try {
// ...
} catch (Exception ex) {
WorkFlowProblems.Add(new OrderNotSentException("Email did not work", ex));
View.ShowError("Could not send order!");
}
Here you make a new exception and set it's "inner exception" to be original cause. This is a good way for multi-part systems to have the right level of information about what went wrong and at what level.
Doing this preserves the stack trace. In your example, it's not useful, however, you could catch the exception, log it and then rethrow so that the exception bubbles up to be handled by code higher up.
The place where throwing exception (in my opinion) is MOST useful is when you want to create an instance of a new object and there's some possibility that the instance needs to fail in creation, in which case the instance can be made to remain null (since constructors don't "return" anything... so for example...
Foo foo = new Foo();//
//at this line foo may or may not be the exact thing you want it to be, depending on whatever conditions made the creation of Foo possible.
So, Foo throws an exception you can do this:
Foo foo = null;
try{
foo = new Foo();
}catch(FooException fe){
//here you can find out if Foo didn't get instantiated as you wanted it to
}
//and here you can test if foo is still null.
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.