[armedbear-devel] Catching CL errors in java

Alessio Stalla alessiostalla at gmail.com
Wed Feb 20 09:21:08 UTC 2013


No problem! I'm glad you sorted it out.

On Wed, Feb 20, 2013 at 2:16 AM, Jonathan Fischer Friberg
<odyssomay at gmail.com> wrote:
> I got it. :D
>
> It was my thread pool that tricked me. Apparently, if there's an exception
> in a thread pool, it won't be printed or anything, it will just disappear
> (unless specifically catched).
> I tried to catch 'Exception', but the thrown exception is not actually a
> subclass of 'Exception', it's a subclass of 'Error'! So the exception
> escaped my catch
> clause, and because the code was running inside the thread pool, it would
> not be displayed. So I changed the class to catch to 'Throwable' and now
> it's working
> as it's supposed to (with the let method).
>
> Thanks for all your help Alessio! :D
>
> Jonathan
>
>
> On Tue, Feb 19, 2013 at 6:23 PM, Alessio Stalla <alessiostalla at gmail.com>
> wrote:
>>
>> On Tue, Feb 19, 2013 at 6:12 PM, Jonathan Fischer Friberg
>> <odyssomay at gmail.com> wrote:
>> > Threads should not be a problem. I have a thread pool (of one thread),
>> > where
>> > all evals are executed (had this problem before :) ).
>> >
>> > If I do the let version in the repl, I seem to get both an exception and
>> > a
>> > CL error. Like this:
>> >
>> > CL-USER(1): (let ((*debugger-hook*  #'sys::%debugger-hook-function)) (/
>> > 1
>> > 0))
>> > org.armedbear.lisp.Interpreter$UnhandledCondition: Unhandled lisp
>> > condition:
>> > Arithmetic error DIVISION-BY-ZERO signalled.
>> >         at
>> > org.armedbear.lisp.Interpreter$1.execute(Interpreter.java:569)
>> >         at org.armedbear.lisp.LispThread.execute(LispThread.java:653)
>> >         ...stack trace...
>> > #<THREAD "interpreter" {5B6ADD}>: Debugger invoked on condition of type
>> > ERROR
>> >   Caught org.armedbear.lisp.Interpreter$UnhandledCondition: Unhandled
>> > lisp
>> > condition: Arithmetic error DIVISION-BY-ZERO signalled..
>> >
>> > and I get into the debugger.
>>
>> That's correct, because the Java exception is caught by the REPL and
>> turned again into a Lisp condition. Your debugger hook is only in
>> effect inside the LET, what happens "outside" is under the control of
>> the REPL.
>>
>> > If I use the setf version in the repl, It throws an exception and exits
>> > (which I think is the behavior I want).
>>
>> In this case, you globally override the default REPL behaviour, and
>> that's why it exits.
>>
>> > If I use setf with .eval, I get:
>> > Maximum error depth exceeded (11 nested errors) with 'Arithmetic error
>> > DIVISION-BY-ZERO signalled.'.
>> >
>> > I have added (/ 1 0) to the eval call, so that happens after eval has
>> > been
>> > called 11 times. But the exception never reaches my java code.
>>
>> I cannot explain that! And I cannot explain your subsequent message,
>> either. Maybe you've hit a bug? Anyone has an idea?
>>
>> Alessio
>>
>> > Jonathan
>> >
>> >
>> > On Tue, Feb 19, 2013 at 6:03 PM, Alessio Stalla
>> > <alessiostalla at gmail.com>
>> > wrote:
>> >>
>> >> Sorry, to clarify: defparameter is a friend of setf when used like you
>> >> did, which is not how it's normally used (defparameter defines a
>> >> global dynamic variable and, as a side effect, modifies its value if
>> >> it already had one, but you never use it just for its side effect).
>> >> You can imagine defparameter as a shorthand for a defvar followed by a
>> >> setf.
>> >>
>> >> On Tue, Feb 19, 2013 at 6:00 PM, Alessio Stalla
>> >> <alessiostalla at gmail.com>
>> >> wrote:
>> >> > I don't think the package is the culprit. Your package most probably
>> >> > USEs the CL package, or many other things would not work as you'd
>> >> > expect.
>> >> >
>> >> > Answering your earlier question, the correct way would be (setf
>> >> > *debugger-hook* ...) rather than defparameter, or even better binding
>> >> > instead of assigning - (let ((*debugger-hook* ...)) (do-your-stuff)).
>> >> >
>> >> > But I don't think that can make a difference between working and not
>> >> > working at all. It is more of a question of good style. Perhaps
>> >> > you're
>> >> > not considering thread-local bindings? If you run your
>> >> > defparameter/setf form on one thread, but .eval is called on another
>> >> > thread (and with a GUI involved, that is very probable), then chances
>> >> > are that the code in your .eval call is running in a dynamic
>> >> > environment where *debugger-hook* is locally rebound, and thus the
>> >> > global binding that you modify with defparameter/setf is shadowed.
>> >> > You
>> >> > can detect it by printing the value of *debugger-hook* in an .eval
>> >> > call triggered by the GUI. If that is the case, you should make sure
>> >> > to assign a new value to *debugger-hook* on the right thread, or,
>> >> > better, to use (let ...) as shown above. Let me stress that using LET
>> >> > is usually what you want in Lisp, especially when dealing with
>> >> > dynamic
>> >> > variables; a good rule of thumb is: avoid SETF and friends
>> >> > (defparameter is a friend) unless you're working on local variables.
>> >> > Of course, experts know when and how to break the rules :D but if
>> >> > you're a beginner, sticking to that style will make things easier to
>> >> > understand and debug, once you enter the right mindset.
>> >> >
>> >> > hth,
>> >> > Alessio
>> >> >
>> >> > On Tue, Feb 19, 2013 at 5:50 PM, Jonathan Fischer Friberg
>> >> > <odyssomay at gmail.com> wrote:
>> >> >> It might be that I'm in the wrong package. Although the repl is in
>> >> >> cl-user,
>> >> >> and even if I change to that package the code in the previous mail
>> >> >> has
>> >> >> no
>> >> >> effect.
>> >> >>
>> >> >> Jonathan
>> >> >>
>> >> >>
>> >> >> On Tue, Feb 19, 2013 at 5:36 PM, Jonathan Fischer Friberg
>> >> >> <odyssomay at gmail.com> wrote:
>> >> >>>
>> >> >>> I don't know if this is the correct way to do it, but I did:
>> >> >>>
>> >> >>> (defparameter *debugger-hook*  #'sys::%debugger-hook-function)
>> >> >>>
>> >> >>> In the repl (from running java -jar abcl.jar), this worked as
>> >> >>> expected.
>> >> >>> However, I can't seem to get it working with the .eval function of
>> >> >>> my
>> >> >>> interpreter instance.
>> >> >>>
>> >> >>> Jonathan
>> >> >>>
>> >> >>>
>> >> >>> On Tue, Feb 19, 2013 at 5:07 PM, Alessio Stalla
>> >> >>> <alessiostalla at gmail.com>
>> >> >>> wrote:
>> >> >>>>
>> >> >>>> Short story: if you call into Lisp using the JSR-223 API,
>> >> >>>> conditions
>> >> >>>> are automatically rethrown as Java exceptions.
>> >> >>>>
>> >> >>>> Long story: the way this is implemented is by binding
>> >> >>>> *debugger-hook*
>> >> >>>> to an internal, probably undocumented function, that already does
>> >> >>>> what
>> >> >>>> you want. It is called sys::%debugger-hook-function.
>> >> >>>>
>> >> >>>> On Tue, Feb 19, 2013 at 4:25 PM, Jonathan Fischer Friberg
>> >> >>>> <odyssomay at gmail.com> wrote:
>> >> >>>> > I should add that a solution from inside CL would also work. I'm
>> >> >>>> > using
>> >> >>>> > the
>> >> >>>> > ABCL eval to execute all code, so maybe I could wrap the call
>> >> >>>> > with
>> >> >>>> > something
>> >> >>>> > like this:
>> >> >>>> >
>> >> >>>> > (handler-case
>> >> >>>> >    (... do-stuff ...)
>> >> >>>> >    (... catch CL-condition + throw java exception ...))
>> >> >>>> >
>> >> >>>> > I don't know if that would work. Also, my CL skills are not good
>> >> >>>> > enough
>> >> >>>> > to
>> >> >>>> > finish the code above (how do I capture all conditions?), so
>> >> >>>> > help
>> >> >>>> > would
>> >> >>>> > be
>> >> >>>> > appreciated.
>> >> >>>> >
>> >> >>>> > Jonathan
>> >> >>>> >
>> >> >>>> >
>> >> >>>> > On Tue, Feb 19, 2013 at 3:30 PM, Jonathan Fischer Friberg
>> >> >>>> > <odyssomay at gmail.com> wrote:
>> >> >>>> >>
>> >> >>>> >> Hi again, :)
>> >> >>>> >>
>> >> >>>> >> I'm currently running CL-code from java. The gui is completely
>> >> >>>> >> implemented
>> >> >>>> >> on the java side. It would be nice if all errors occuring
>> >> >>>> >> inside
>> >> >>>> >> abcl
>> >> >>>> >> could
>> >> >>>> >> be captured from the java side (to be displayed in the gui as
>> >> >>>> >> an
>> >> >>>> >> error). Is
>> >> >>>> >> that possible?
>> >> >>>> >>
>> >> >>>> >> Jonathan




More information about the armedbear-devel mailing list