Re: Redirecting error messages
Thomas Russ <[email protected]> Mon, 14 Jan 2008 11:08:15 -0800
| Newsgroups | gmane.comp.ai.powerloom |
|---|---|
| Message-ID | <[email protected]> |
General note: This reply is specific to the Common Lisp version of
PowerLoom.
On Jan 12, 2008, at 12:29 PM, Magnus Malm wrote:
> Hello
>
> I do not understand how the error messages are generated. They
> appear to go through some other stream than *standard-output*. (I
> have tried to bind both *standard-output* and *error-output* to a
> file but nothing is streamed to the file, the error messages are
> still printed to the REPL.)
The issue is that PowerLoom uses Stella to implement the language.
And Stella has its own streams for writing standard output, error
output, etc. These are mapped (in the Common Lisp implementation) to
*standard-output* and *error-output*, but the mapping isn't dynamic.
If you change the values of the Lisp special variables, their original
values have already been captured by Stella.
Possible solutions below.
> What I want to do is to capture all error (And warning) messages and
> redirect them to a string (for futher processing) but I do not
> understand the underlying code that generates these messages.
> Apparently, a stream is created with MAKE-STRING-OUTPUT-STREAM, but
> I have no idea when, or where, this stream is created, let alone the
> name of it. (It might be worth mentioning that I use the struct
> version of powerloom)
The exception mechanism should be the same in both versions of Common
Lisp, since we use the native exception mechanism. It is good to
mention the struct item, though, since other things are often different.
I think that you have two options:
1. Redirect the the output of cl:*error-output* (and perhaps also
cl:*standard-output*) BEFORE loading PowerLoom. In that case, the
initialization when PowerLoom loads should get the values existing at
the time of loading. If you don't want to do the re-direction
globally, you should be able to bind the values around the loading and
initialization of PowerLoom.
(let ((*error-output* your-stream-here))
(load ".../load-powerloom"))
2. You could redirect the output when running PowerLoom by binding
the global variables stella::standard-output, stella::warning-output
and stella::error-output. These require objects of type
stella::output-stream. Constructing such objects involves invoking
the stella:new-output-stream function and then setting the native-
stream slot. The native-stream slot accessor differs between the CLOS
and struct versions of Stella.
(let ((my-stella-stream (stella::make-output-stream)))
;; CLOS
(setf (stella::%native-stream my-stella-stream) my-lisp-stream)
;; STRUCT
(setf (stella::%output-stream.native-stream my-stella-stream)
my-lisp-stream)
(let ((stella::error-output my-stella-stream)))
... PowerLoom API functions here ...
))
> Perhaps I am going the wrong way here but I have not found any
> documentation on how to handle exceptions, and wether or not
> exceptions are thrown when there's a parse error in a query for
> instance.
Exceptions are implemented as sub-types of native exceptions. They
are thrown by the code and handled by the powerloom listener. If you
aren't running through the listener, then the exceptions should be
thrown normally.
> I use LISP and only the API functions, s-retrieve, s-ask, etc. It is
> s-retrieve I use the most and would really like to be able to handle
> parse errors and make my own error handling for this (quite simply
> just send the entire error message to the user (who does not have
> the REPL infront of him/her :))).
Well, the interface functions should throw the errors themselves, for
example, using SBCL:
> (pli:s-retrieve "all (fred ?x)" null-string null)
ERROR: Undeclared predicate or function reference: `FRED'.
Error occurred while parsing the proposition:
(KAPPA (?X) (FRED ?X))
[Condition of type PROPOSITION-ERROR]
The full exception hierarchy is shown below. These are all defined in
the Common Lisp STELLA package. The most interesting for general use
are CLASH, READ-EXCEPTION, PARSING-EXCEPTION and PROPOSITION-
EXCEPTION. The READ-EXCEPTION is what you will get if there is, for
example, not enough parentheses in the form, since that is detected at
low-level in the code, before any attempt is made to parse the results
as a PowerLoom form. Most PowerLoom exceptions will be subtypes of
LOGIC-EXCEPTION.
NATIVE-EXCEPTION
STELLA-EXCEPTION
INPUT-OUTPUT-EXCEPTION
READ-EXCEPTION
END-OF-FILE-EXCEPTION
NO-SUCH-FILE-EXCEPTION
FILE-ALREADY-EXISTS-EXCEPTION
UNHANDLED-EXCEPTION
EVALUATION-EXCEPTION
NO-SUCH-OBJECT-EXCEPTION
NO-SUCH-CONTEXT-EXCEPTION
UNDEFINED-CLASS-EXCEPTION
BAD-ARGUMENT-EXCEPTION
OBJECT-NOT-CLASS-EXCEPTION
INCOMPATIBLE-QUANTITY-EXCEPTION
OBJECT-ALREADY-EXISTS-EXCEPTION
LOGIC-EXCEPTION
EXPLAIN-EXCEPTION
EXPLAIN-NO-QUERY-EXCEPTION
EXPLAIN-NO-SOLUTION-EXCEPTION
EXPLAIN-NO-MORE-SOLUTIONS-EXCEPTION
EXPLAIN-NOT-ENABLED-EXCEPTION
EXPLAIN-NO-SUCH-LABEL-EXCEPTION
EXPLAIN-QUERY-TRUE-EXCEPTION
TERM-GENERATION-EXCEPTION
PROPOSITION-ERROR
PARSING-ERROR
CLASH
FAIL-EXCEPTION
QUERY-THREAD-LIMIT-VIOLATION
Is there some particular parsing error you are running into that isn't
generating a real error?
Note that warnings will not throw exceptions, but will only print
information, though.