How to get Clojure exception notification when they happen on the EDT? - swing

I've just been scratching my hairs for a long time with an error I couldn't find. It turned out to be an arity exception but apparently because it happened on the EDT I couldn't "see" it. It didn't show in the "lein run" terminal when run from a terminal and it didn't show in any Emacs buffer when run from Emacs.
After a very long time I ended up doing this:
(try (function-call-with-arity-error ...) (catch Exception e (println e)
and, at last, thanks to this, I got to see this printed:
#<ArityException clojure.lang.ArityException: wrong number of args passed to...
and hence I've been able to find my error.
And if I do this:
(do
(println "trying...")
(arity-error-here-on-purpose) ; this ones throws the arity error
(println "done")
)
Then the terminal prints "trying..." but never gets to "done...".
I tried setting a default uncaught exception handler: the exception isn't getting caught. It's as if the program or the EDT was "stuck" after the arity exception (without printing anything anywhere).
How am I suppose to deal with this the next time? Because I couldn't see any message anywhere it took me a really long time to find. Once again: nothing in the 'lein run' terminal and nothing in any Emacs buffer.
Should I create a function that wraps calls that should happen on the EDT inside try / catch manually and that then logs/println the exception?
Also note that this is in a relatively "long" Clojure app: 1000 lines of code, so I can't paste it here and I couldn't reproduce that behavior in a short example (but it happens consistently in my app).

You can register an uncaught exception handler with a Thread so you don't have to wrap all the calls that can occur on the EDT.
Thread.UncaughtExceptionHandler
Try registering one with the EDT and seeing if this gives you the desired behavior.

Related

Exceptions in Lablgtk callbacks

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.

Uncatchable exception in ColdFusion?

I stumbled upon a very weird issue in ColdFusion which might very well be a bug, but I wanted to post it here in case I was missing something.
It seems that cfindex is throwing an uncatchable exception when trying to index invalid files.
I'm not entirely sure yet what consists of an invalid file, but the issue occurs with a valid PDF file, but that doesn't have a PDF extension. Obviously, the problem can easily be fixed by adding a valid extension, but that's not the scope of the question.
<cftry>
<cfindex
collection="some_collection"
action="update"
key="//someserver/some_file_without_extension">
After index
<cfcatch type="any">
Exception caught
</cfcatch>
<cffinally>
Finally block
</cffinally>
</cftry>
Completed
When running the above code, the only thing that is output is Finally block, therefore it's like if there is an exception thrown, but which cannot be caught.
I even tried with type="java.lang.Exception", type="java.lang.Throwable" and type="searchengine" and nothing works.
The only way I found to detect such exceptions is to check a boolean flag in the finally block, but gracefully recovering form those errors is very cumbersome.
Another very weird thing that occurs is that right after the issue is encountered, if I refresh the page in the browser, I'll get the following error:
HTTP Error 503.0 - Server Error
The service is unavailable.
Module IsapiModule
Notification ExecuteRequestHandler
Handler JWildCardHandler
Error Code 0x00000000
Then after refreshing again, I get Finally block and if I keep refreshing the same behavior occurs over and over (Finally block then 503 error).

Restkit: getting objc_exception_throw in saveContextToPersistentStore, RKManagedObjectRequestOperation.m

I am getting, just for once every app runtime, an exception in the method saveContextToPersistentStore in RKManagedObjectRequestOperation.m: on line
success = [contextToSave save:&localError];
success is YES, localError is nil. I can continue the program execution in debugger.
I tried to wrap it with #try block but with no success (as something else took care of this) to get more information why it happens.
Can you help me to investigate the cause of this? Is this something I should pay attention to? This answer may targets this issues. But I am not sure, if the problem is local or caused in higher layers (Restkit mapping).
Stack:

Async exception not caught by debugger

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.

How do uncaught exceptions behave in threads?

I'm trying to understand what is going on with a program where I've got exceptions "disappearing" without any notice (and a thread stops working).
The simplest case I could come up with to reproduce the issue is this:
(defn -main []
(let [a (future (do (println "Ouch... ")
(/ 0 0)
(println "We never arrive here")))]
(Thread/sleep 1000)
(println "Hmmmm" #a)))
Surely enough, when run at the repl (or using lein run), I get an exception:
so.core> (-main)
Ouch...
ArithmeticException Divide by zero clojure.lang.Numbers.divide (Numbers.java:156)
Which is the behavior I expected.
However now if I remove the dereferencing of the future:
(defn -main []
(let [a (future (do (println "Ouch... ")
(/ 0 0)
(println "We never arrive here")))]
(Thread/sleep 1000)
(println "Hmmmm")))
Here's the output:
so.core> (-main)
Ouch...
Hmmmm
nil
so.core>
So the future is executed (otherwise "Ouch..." wouldn't be print) and obviously an exception is then thrown (otherwise "We never arrive here" would print)... But that exception is nowhere to be found and the program continues as if everything was fine.
Apparently as long as I don't try to dereference the future, the thread can silently die, in the middle of its work (in this case printing to stdout), and the exception is nowhere to be found.
Is this normal?
Am I supposed to find a (stack)trace of that exception in one of my Emacs / cider buffers?
What would be an idiomatic way to have a future doing its work (e.g. consuming messages from a queue) and yet "warn" me when something goes wrong?
Should I wrap every future call inside try/catch blocks?
Should I set a default uncaught exception handler?
Am I not supposed to run a "non-stopping" thread using a future?
Basically I'm very confused by the behaviour of Java / Clojure here and would like to have both explanation as to why it's behaving that way and how I'm supposed to deal with this issue.
In clojure future is a macro that produces a reified java.util.concurrent.Future, and dereferencing it calls the Future.get method. That method can throw an ExecutionException which represents an uncaught exception in the thread. So if you don't dereference you don't call .get and you don't get the exception.
The clojure doc site has the source, so you can see the actual implementation here.
If you don't want to dereference I suppose you should try/catch in the thread, and handle in whatever way you choose.