4 Errors
dxtr edited this page 2026-10-18 16:05:50 +02:00

Errors

icu-error

cl-icu signals one flat condition class, icu-error, a subclass of error, in three cases:

  1. An ICU function reported an error through its UErrorCode, such as running out of memory or missing data.
  2. cl-icu saw that a call cannot succeed and stopped it before it reached ICU: an index past the end of the text, start after end, a line that spans paragraphs, an unknown property name, a property kind cl-icu does not read.
  3. The ICU the process finds cannot be used: there is no libicuuc to load, it is no ICU from 50 to 99, or it lacks a function cl-icu binds. Loading cl-icu, starting a saved image, load-icu and deficu meet these; see ICU versions and saved images.
Reader Value
icu-error-message what went wrong, in terms of the cl-icu call (a string)
icu-error-hint what to do about it (a string), or nil
icu-error-code the integer UErrorCode ICU returned, or nil when cl-icu caught the problem itself
icu-error-function the ICU function that failed, such as "ubrk_open", or nil
icu-error-name a keyword naming the code, such as :memory-allocation-error for U_MEMORY_ALLOCATION_ERROR, or nil (a function, not a slot reader)

The report prints the message, then the hint, then the ICU function and code when there is one.

A problem cl-icu caught itself:

(handler-case (icu:bidi-runs "abc" :start 2 :end 9)
  (icu:icu-error (e)
    (values (princ-to-string e) (icu:icu-error-code e))))
;; => "END is 9, past the end of the text, which has 3 characters.
;;     START and END are character indexes into the text, with
;;     0 <= START <= END <= its length."
;;    NIL

An error reported by ICU reads like this:

Could not find the line boundaries: ICU ran out of memory.
(ICU: ubrk_open returned U_MEMORY_ALLOCATION_ERROR)

The errors you can meet

Situation Message Hint
end past the text END is 9, past the end of the text, which has 3 characters. START and END are character indexes into the text, with 0 <= START <= END <= its length.
start after end START is 3, after END (1). (same)
a bidi line across a paragraph separator Characters 1 to 4 span more than one paragraph: a paragraph ends at 3. Pass the bounds of one line, which lies in one paragraph; find the paragraphs with BIDI-PARAGRAPHS. To reorder the whole text, omit START and END.
unknown property ICU knows no Unicode property named :NONSENSE. Name a property of the Unicode Character Database, as a keyword such as :EAST-ASIAN-WIDTH or a string such as "East_Asian_Width" or "ea".
numeric, string or mask property :NUMERIC-VALUE is a mask, numeric or string property, which cl-icu does not support. CHAR-PROPERTY reads binary properties, such as :ALPHABETIC, and enumerated ones, such as :GENERAL-CATEGORY.
ICU out of memory Could not task: ICU ran out of memory. —
ICU data missing or unreadable Could not task: ICU's data for it is missing. / ICU could not read its data files. Check that the ICU data package for this ICU version is installed.
ICU data damaged Could not task: ICU's data for it is damaged. Reinstall the ICU data package.
feature not in this ICU build Could not task: this ICU build does not support it. Use an ICU build with the feature enabled.
any other ICU error Could not task: ICU reported an error. —

task says what cl-icu was doing, such as "find the line boundaries for locale "th"", "resolve the bidirectional text" or "normalize the text to NFC".

Dispatch on icu-error-name when you need to tell ICU's errors apart, never on the message text.

Bad arguments: type-error

Arguments of the wrong type, or keywords outside the documented choices, signal a standard type-error before anything reaches ICU:

  • a text that is not a string, or a locale that is not a string or nil
  • start or end that is not a non-negative integer
  • a direction other than :auto, :auto-rtl, :ltr, :rtl, the type bidi-direction
  • a boundary type other than :grapheme, :word, :line, :sentence, the type boundary-type
  • a normalization form other than :nfc, :nfd, :nfkc, :nfkd, :nfkc-casefold, the type normalization-form
  • a character argument that is neither a character nor a code point from 0 to #x10FFFF, the type code-point
  • a property name that is neither a keyword nor a string, or a script that is not a string

Every exported function declares the types of its arguments, so SBCL checks them when the call is compiled: a constant of the wrong type is a compiler warning where it is written.

(icu:bidi-runs "abc" :direction :sideways)
;; caught WARNING: Constant :SIDEWAYS conflicts with its asserted type (MEMBER :RTL :LTR :AUTO-RTL :AUTO).

(icu:bidi-runs "abc" :direction (read-from-string ":sideways"))
;; type-error: The value :SIDEWAYS is not of type (MEMBER :RTL :LTR :AUTO-RTL :AUTO) when binding :DIRECTION

So an icu-error always means the arguments were well-formed and the text, the data or ICU itself refused the call.

Things that are not errors

  • An unknown or misspelt locale. ICU falls back to the nearest locale it has, ultimately the root rules, and cl-icu does not report the fallback.
  • An unknown script code: script-name returns nil.
  • A name that matches no character: unicode-name-char returns nil; a character without a name gives nil from char-unicode-name.
  • Empty text: every function accepts "" and returns an empty result (text-boundaries returns (0)).
  • Unassigned and private-use code points: properties return their defaults, such as general category :unassigned or :private-use and script "Zzzz" (Unknown).