Please see #7755661 first. I am using ECL and basically want to execute some code, trap any kind of condition that may occur and then continue execution, without prompting or entering the debugger. This is easy to achieve with the following handler-case macro:
(handler-case
(load "code.lisp") ; this may raise a condition
(error (condition)
(print condition))) ; this prints sth like #<a UNBOUND-VARIABLE>
My only problem is that I cannot find a generic way to print a more meaningful error for the user. Indeed my application is an HTTP server and the output goes to a web page. code.lisp is written by the user and it can raise any kind of condition, I do now want to list them all in my code. I would just like to print the same error message I see on the REPL when I do not use handler-case, but in the HTML page, e.g. for an "unbound variable" error, a string like "The variable VAR is unbound".
By inspecting a condition object of type UNBOUND-VARIABLE
I see it has two slots: SI:REPORT-FUNCTION
, which is a compiled function and SI:NAME
, set to the name of the variable in this case. I guess SI:REPORT-FUNCTION
could be what I need to invoke but how can I call it? If I try:
(handler-case foo (error (condition) (SI::REPORT-FUNCTION condition)))
it tells me that SI:REPORT-FUNCTION is undefined. SI or SYS in ECL is a package for functions and variables internal to the implementation, but I don't worry if my code is not portable, as long as it works.
BTW in other kinds of condition objects there are also other apparently useful slots for my purpose, named SI:FORMAT-CONTROL
and SI:FORMAT-ARGUMENT
, but I cannot access any of them from my code too.
I was looking for somethink alike to the getMessage()
method of Java exception objects in Lisp, but none of my sources ever mentions something like that.
Moreover, is there any hope to be able to get the line number in code.lisp where the error occurred too? Without that it would be difficult for the user to locate the problem in his code.lisp source file. I would really want to provide this information and stopping at the first error is acceptable for me.
In Common Lisp when print escaping is disabled, the error message is printed.
Note that
PRINT
binds*print-escape*
toT
.Using
PRINC
works - it binds*print-escape*
toNIL
.This is described in CLHS 9.1.3 Printing Conditions.
Also note, when you have an object, which has a slot and the value of this slot is a function, then you need to get the slot value using the function
SLOT-VALUE
and then useFUNCALL
orAPPLY
and call the function with the correct arguments.If you have a condition of type
simple-condition
then it has a format-control and a format-argument information. This is described with an example how to use it forFORMAT
in CLHS Function SIMPLE-CONDITION-FORMAT-CONTROL, SIMPLE-CONDITION-FORMAT-ARGUMENTS