[Cairo] Error handling in Cairo
cworth at east.isi.edu
Fri Sep 26 12:21:59 PDT 2003
[A quick note on Cairo error handling. I want to put this in the
documentation, but right now, this list is the best place for that we
have. It should be easier to make "real" documentation as the API
churn calms down. And, of course, volunteers are always welcome.]
Cairo has an error handling system designed to be easy to use, robust
in the face of misuse, and to have minimal impact on application code.
Except for some query functions, all state-based functions in Cairo,
(those that accept a pointer to a cairo_t object), have a void return
type. These functions give no indication whether the operation
succeeded or not. Instead the success or failure of each operation is
saved in a status field within the cairo_t object. The status field
can be queried in either symbolic or string form:
cairo_status (cairo_t *cr);
const char *
cairo_status_string (cairo_t *cr);
That is pretty standard error handling for a state-based API.
The more interesting part is that as soon as the status field is set
to an error condition, the cairo_t object shuts down entirely. If the
status field in a cairo_t indicates a previous error, a call to any
function with that cairo_t will return immediately with no effects
This means that it is always safe to continue to call Cairo functions
even after an error may have occurred. A detected error will not lead
to a crash.
The benefit to the programmer is that it is not necessary to query the
status after each call to a Cairo function. It is sufficient to query
the status value when convenient. For example, it is recommended to
practice to call cairo_function in natural series, only calling the
cairo_status function once at the end of the series.
Additionally, since an error causes a complete shutdown of Cairo, no
output will be produced after an error. This makes it harder for
application errors to remain undetected even without consistent calls
to the status query functions.
PS. Keith deserves credit for coming up with this approach for error
handling. I like it a lot. I don't know what previous systems may have
inspired the approach.
PPS. I recently added code that violates the rule stated above. A
call to cairo_set_target_surface will now clear a previous
NO_TARGET_SURFACE error. That was a mistake. I'll remove that code.
More information about the cairo