Common Lisp the Language, 2nd Edition

Next: Program Interface to Up: Survey of Concepts Previous: Condition Handlers

## 29.3.18. Printing Conditions

When `*print-escape*` is `nil` (for example, when the `princ` function or the `~A` directive is used with `format`), the report method for the condition will be invoked. This will be done automatically by functions such as `invoke-debugger`, `break`, and `warn`, but there may still be situations in which it is desirable to have a condition report under explicit user control. For example,

    (let ((form '(open "nosuchfile")))
      (handler-case (eval form)
        (serious-condition (c)
          (format t "~&Evaluation of ~S failed:~%~A" form c))))

might print something like

    Evaluation of (OPEN "nosuchfile") failed:
    The file "nosuchfile" was not found.

Some suggestions about the form of text typed by report methods:

- The message should generally be a complete sentence, beginning with a capital letter and ending with appropriate punctuation (usually a period).

- The message should not include any introductory text such as ```Error:`'' or ```Warning:`'' and should not be followed by a trailing newline. Such text will be added as may be appropriate to context by the routine invoking the report method.

- Except where unavoidable, the tab character (which is only semi-standard anyway) should not be used in error messages. Its effect may vary from one implementation to another and may cause problems even within an implementation because it may do different things depending on the column at which the error report begins.

- Single-line messages are preferred, but newlines in the middle of long messages are acceptable.

- If any program (for example, the debugger) displays messages indented from the prevailing left margin (for example, indented seven spaces because they are prefixed by the seven-character herald ```Error:` ''), then that program will take care of inserting the appropriate indentation into the extra lines of a multi-line error message. Similarly, a program that prefixes error messages with semicolons so that they appear to be comments should take care of inserting a semicolon at the beginning of each line in a multi-line error message. (These rules are important because, even within a single implementation, there may be more than one program that presents error messages to the user, and they may use different styles of presentation. The caller of `error` cannot anticipate all such possible styles, and so it is incumbent upon the presenter of the message to make any necessary adjustments.)

[Note: These recommendations expand upon those in section 24.1.-GLS]

When `*print-escape*` is not `nil`, the object should print in some useful (but usually fairly abbreviated) fashion according to the style of the implementation. It is not expected that a condition will be printed in a form suitable for `read`. Something like `#<ARITHMETIC-ERROR 1734>` is fine.

X3J13 voted in March 1989 (ZLOS-CONDITIONS) to integrate the Condition System and the Object System. In the original Condition System proposal, no function was provided for directly accessing or setting the printer for a condition type, or for invoking it; the techniques described above were the sole interface to reporting. The vote specified that, in CLOS terms, condition reporting is mediated through the `print-object` method for the condition type (that is, class) in question, with `*print-escape*` bound to `nil`. Specifying `(:report fn)` to `define-condition` when defining condition type C is equivalent to a separate method definition:

    (defmethod print-object ((x C) stream)
      (if *print-escape*
          (call-next-method)
          (funcall #'fn x stream)))

Note that the method uses fn to print the condition only when `*print-escape*` has the value `nil`.

Next: Program Interface to Up: Survey of Concepts Previous: Condition Handlers