Skip to main content

Chapter 12: Error Handling and Avoidance

  • Chapter
Common Lisp Recipes
  • 2030 Accesses

Abstract

Errors happen. There’s no magic bullet that’ll help you to avoid all errors your code could possibly ever encounter. But you can, of course, try to program defensively and anticipatory so that typical errors are noticed early and avoided before they can harm you. And you can be prepared to handle those errors that can’t be avoided.

This is a preview of subscription content, log in via an institution to check access.

Access this chapter

Chapter
USD 29.95
Price excludes VAT (USA)
  • Available as PDF
  • Read on any device
  • Instant download
  • Own it forever
eBook
USD 79.99
Price excludes VAT (USA)
  • Available as EPUB and PDF
  • Read on any device
  • Instant download
  • Own it forever
Softcover Book
USD 99.99
Price excludes VAT (USA)
  • Compact, lightweight edition
  • Dispatched in 3 to 5 business days
  • Free shipping worldwide - see info

Tax calculation will be finalised at checkout

Purchases are for personal use only

Institutional subscriptions

Notes

  1. 1.

    In fact, Lisp is not only not an exception but actually kind of a leader of the pack. See https://en.wikipedia.org/wiki/Exception_handling#History .

  2. 2.

    Unless you count CLtL2. But it was obviously more written like a standards document and less like a textbook.

  3. 3.

    SQRT, of course, wouldn’t care (see Recipe 4-8).

  4. 4.

    On the other hand, that means you can’t evaluate a form like (CHECK-TYPE 42 INTEGER) interactively in the REPL to check a type. For that, use TYPEP.

  5. 5.

    Where we’re thrown into the debugger (see Recipe 16-3).

  6. 6.

    And as CASE has “relatives” CCASE and ECASE, so does TYPECASE have CTYPECASE and ETYPECASE.

  7. 7.

    See http://mathworld.wolfram.com/DotProduct.html .

  8. 8.

    See https://en.wikipedia.org/wiki/Assertion_%28software_development%29 .

  9. 9.

    You’ll find out that this is rather tricky if you want to mimic CHECK-TYPE’s error messages and at the same time avoid double evaluation.

  10. 10.

    This is, of course, only meaningful if (a) the assertions were only ever meant to test for programmer errors and not for user errors and (b) removing the assertions doesn’t alter the code’s behavior; that is, if the code in the assertions doesn’t have any inadvertent side effects.

  11. 11.

    If you use ASDF (see Recipe 18-1), look up the :FORCE keyword argument for enforced recompilation of all files.

  12. 12.

    Even multiple inheritance, as witnessed for example by READER-ERROR or SIMPLE-WARNING.

  13. 13.

    That’s why the standard mostly talks about condition types instead of condition classes. However, you’ll also find (for example in section 9.1) sentences like, “A hierarchy of condition classes is defined in Common Lisp.”

    This is essentially a historical remnant. The condition system specification was retrofitted to coexist with CLOS when the standard was created.

  14. 14.

    The condition reporter can also be just a constant string.

  15. 15.

    For the creation of conditions and condition classes, see Recipe 12-3.

  16. 16.

    Using INVOKE-DEBUGGER. See more in Recipe 16-3.

  17. 17.

    Unless you’ve established at least one restart (see Recipe 12-6) around the ERROR form.

  18. 18.

    And it establishes a handler that we’ll discuss in Recipe 12-7.

  19. 19.

    And also other functions and macros; see, for example, Recipe 12-2.

  20. 20.

    To be picky, and if that condition is not already handled within the form.

  21. 21.

    But it doesn’t have to. See https://en.wikipedia.org/wiki/IEEE_754-1985#Positive_and_negative_infinity .

  22. 22.

    It doesn’t matter whether your implementation really does it this way. Conceptually it’ll work like this more or less. But implementations might by default “hide” some stack frames from you to not clutter up backtraces. If you want to understand how your Lisp implements facilities like catch tags or special variable bindings, you might thus need to convince it to “unhide” those frames. For example, look at the documentation for DBG:*PRINT-BINDING-FRAMES*, DBG:*PRINT-CATCH-FRAMES*, DBG:*PRINT-HANDLER-FRAMES*, and DBG:*PRINT-RESTART-FRAMES* in LispWorks.

  23. 23.

    See Recipe 4-9 for PARSE-INTEGER.

  24. 24.

    For DEFINE-CONDITION, see Recipe 12-3; for the function ERROR, see Recipe 12-4.

  25. 25.

    Except that this function can’t be called with FUNCALL or APPLY but only with INVOKE-RESTART, as we’ll see soon.

  26. 26.

    This is how it looks in the LispWorks REPL, but it should work more or less the same in any Lisp.

  27. 27.

    As with DEFINE-CONDITION, this can not only be a string but also a function.

  28. 28.

    The recursive approach shown here will have the effect that you can have “nested” errors with “unnecessary” stack frames. An alternative approach without recursion is shown in the example on page 354.

  29. 29.

    My apologies for using an ad hoc term here, but there’s no official name for this function. (The term restart function, which suggests itself, is already used for something else; see page 354.)

  30. 30.

    This is rarely used. A more typical usage is to deploy this macro implicitly. See the HyperSpec entry for RESTART-CASE.

  31. 31.

    And it would be a good exercise to implement the CHECK-TYPE macro yourself, with restarts and all.

  32. 32.

    See https://en.wikipedia.org/wiki/Collatz_conjecture .

  33. 33.

    One could even argue that this is its main purpose, as the signaling of the warning will have no effect in the absence of handlers for it.

  34. 34.

    See page 88 for a discussion of the math involved here.

  35. 35.

    Everything you need to know about conditions, handlers, and restarts to fully understand this example is explained in previous recipes of this chapter. Refrigerators are discussed in the chapter about household appliances.

  36. 36.

    Again, some implementations will really do it like this and some won’t. The underlying mechanism, however, will be the same nevertheless.

  37. 37.

    That’s only the CLOSE-DOOR form in our example.

Author information

Authors and Affiliations

Authors

Electronic Supplementary Material

Below is the link to the electronic supplementary material.

chapter-12 (zip 3 kb)

Rights and permissions

Reprints and permissions

Copyright information

© 2016 Edmund Weitz

About this chapter

Cite this chapter

Weitz, E. (2016). Chapter 12: Error Handling and Avoidance. In: Common Lisp Recipes. Apress, Berkeley, CA. https://doi.org/10.1007/978-1-4842-1176-2_12

Download citation

Publish with us

Policies and ethics