Catching error messages


#1
(if (eq 'nothing (ignore-errors (my-function) t))
    (princ "An error occurred")
    (princ "No error occurred"))

This works to detect if an error occurs in (my-function), but if an error does occur it doesn’t show the error message.

How can I simultaneously detect an error and continue, while also displaying the error message? Is it possible in vanilla uLisp or will I need to add custom functions?


#2

Currently it’s not possible to detect what error caused an error in this situation. I’m not sure how it could be provided without implementing the full Common Lisp condition system.


#3

I’ve just remembered that on another thread @mgr proposed a workaround for this. See:

Error handling in uLisp


#4

Well, I can’t say I didn’t know about that one… sucks it can’t be implemented in pure vanilla uLisp.


#5

On a little more thought, I had a look at the “Common Lisp condition system” and it isn’t terribly complicated. All a condition is, is a type of the error (a symbol), a string describing the error, and optionally the offending object.

uLisp already has those concepts, you would just need to pack them in a list. This could then be used by (handler-bind).

Then instead of using the MUFFLEERRORS flag to tell you if you’re inside an (ignore-errors) or not, you just don’t do anything with the error. If it bubbles up to the top level REPL, it, wasn’t handled, so then print it.

Instead of printing an error, error() and error2() would stuff the details in a global variable and longjmp out. (handler-bind) would make a setjmp trap like (unwind-protect) and (ignore-errors), and if it gets longjmp’ed into it checks the global variable containing the appropriate handler, calling it if it matches or longjmp’ing out if none match. If you longjmp yourself back into the REPL, then print the error, clear it, and then REPL again.

I do notice that the “condition” is a CLOS object, but since uLisp doesn’t have CLOS my best suggestion is to make (handler-bind) work like (case) where you can have multiple condition types match one handler at once. (You could probably even use fn_case() to do the matching for you, calling it like fn_case(cons(error_type, cases), env))


#6

Nice idea, but I think it goes a bit beyond what uLisp is aiming to be; however, if you want to implement it in your fork, of course I’ll be interested to try it out.