4 Errors and Warnings
dxtr edited this page 2026-10-18 16:44:24 +02:00

Errors and Warnings

Errors

Every error cl-svgread signals is an svg-error, whose report says what is wrong and where:

(handler-case (cl-svgread:read-svg "<svg><g id='arrow'><path d='M 0 0 L 4'/></g></svg>")
  (cl-svgread:svg-error (error) (princ-to-string error)))
;; => "The d attribute of the <path> in <g id=\"arrow\"> is malformed at
;;     character 10: expected a number for L, but the value ends."

An element is named by its id, or by its place among its parent's children of its name, such as the 2nd <path> in <g id="layer">, and by the file's name when a file is read. svg-error-location returns that part alone, and svg-error-message the whole message:

(handler-case (cl-svgread:read-svg "<svg><g id='arrow'><path d='M 0 0 L 4'/></g></svg>")
  (cl-svgread:svg-error (error) (cl-svgread:svg-error-location error)))
;; => "the <path> in <g id=\"arrow\">"

XML that xmls cannot read gives the line and column where it stopped, since xmls keeps no line numbers for elements. path-bounds signals one where a transform you give it takes the box beyond what single-floats hold, and cl-svgread/ft2 one for a shape FreeType cannot rasterize (see Rasterizing).

Reading on: the CONTINUE restart

Where SVG's error rules let a reader go on, the error offers a continue restart, whose report says what it does:

  • a malformed attribute is left out, as if it were not there;
  • path data and points are kept up to the error;
  • a use element that refers to nothing, or to an element that holds it, is left out;
  • an element whose transforms, with those around it, scale it beyond 10^30 is left out, with what is inside it;
  • a shape that reaches beyond 10^30 from the drawing's origin, its stroke included, is left out;
  • a shape whose stroke is too wide to draw, as a percentage of a large viewport may make it, is drawn without its stroke.
(handler-bind ((cl-svgread:svg-error #'continue))
  (cl-svgread:read-svg "<svg><path d='M 0 0 L 4 0 L 4'/></svg>"))
;; The path keeps its first line: its points are #(0.0 0.0 4.0 0.0).

Reading as leniently as a web browser does is then:

(handler-bind ((cl-svgread:svg-error #'continue)
               (cl-svgread:svg-warning #'muffle-warning))
  (cl-svgread:read-svg #p"art.svg"))

Input that is not SVG, such as malformed XML or a document whose root is no svg element, offers no restart: continue returns, and the error goes on to the debugger.

Warnings

What cl-svgread leaves out or approximates signals an svg-warning, with svg-warning-message and svg-warning-location, and reading goes on:

(let ((warnings '()))
  (handler-bind ((cl-svgread:svg-warning
                   (lambda (warning)
                     (push (princ-to-string warning) warnings)
                     (muffle-warning warning))))
    (cl-svgread:read-svg "<svg><text>Hi</text>
                            <rect width='4' height='4' fill='url(#g)' stroke-dasharray='none'/>
                          </svg>"))
  (reverse warnings))
;; => ("The <text> in <svg> is left out: cl-svgread does not draw text."
;;     "The fill attribute of the <rect> in <svg> is \"url(#g)\", a gradient or pattern,
;;      which cl-svgread leaves out: the shape is not filled.")

stroke-dasharray='none' changes nothing, so it passes quietly: a warning comes only where the drawing would differ from what SVG draws. Unknown properties and attributes are ignored, as CSS ignores them, and elements of other namespaces are skipped without a word; unknown SVG elements warn.

Muffle the warnings with muffle-warning, as above, or collect them to show the user which parts of a file did not come through.