1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=US-ASCII">
<title>Error handling</title>
<meta name="generator" content="DocBook XSL Stylesheets V1.65.1">
<link rel="home" href="index.html" title="Cairo: A Vector Graphics Library">
<link rel="up" href="language-bindings.html" title="Appendix A. Creating a language binding for cairo">
<link rel="previous" href="bindings-streams.html" title="Streams and File I/O">
<link rel="next" href="bindings-patterns.html" title="Patterns">
<meta name="generator" content="GTK-Doc V1.4 (XML mode)">
<link rel="stylesheet" href="style.css" type="text/css">
<link rel="part" href="pt01.html" title="Part I. Tutorial">
<link rel="part" href="pt02.html" title="Part II. Reference">
<link rel="index" href="ix01.html" title="Index">
<link rel="appendix" href="language-bindings.html" title="Appendix A. Creating a language binding for cairo">
</head>
<body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF">
<table class="navigation" width="100%" summary="Navigation header" cellpadding="2" cellspacing="2"><tr valign="middle">
<td><a accesskey="p" href="bindings-streams.html"><img src="left.png" width="24" height="24" border="0" alt="Prev"></a></td>
<td><a accesskey="u" href="language-bindings.html"><img src="up.png" width="24" height="24" border="0" alt="Up"></a></td>
<td><a accesskey="h" href="index.html"><img src="home.png" width="24" height="24" border="0" alt="Home"></a></td>
<th width="100%" align="center">Cairo: A Vector Graphics Library</th>
<td><a accesskey="n" href="bindings-patterns.html"><img src="right.png" width="24" height="24" border="0" alt="Next"></a></td>
</tr></table>
<div class="sect1" lang="en">
<div class="titlepage">
<div><div><h2 class="title" style="clear: both">
<a name="bindings-errors"></a>Error handling</h2></div></div>
<div></div>
</div>
<p>
The error handling approach in C for Cairo has multiple
elements:
</p>
<div class="itemizedlist"><ul type="disc">
<li><p>
When a method on an object fails, the object is put into
an error state. Subsequent operations on the object do
nothing. The status of the object can be queried with
a function like <a href="cairo-cairo-t.html#cairo-status"><tt class="function">status()</tt></a>.
</p></li>
<li>
<p>
Constructors, rather than
returning<tt class="constant">NULL</tt> on out-of-memory failure,
return a special singleton object on which all
operations do nothing. Retrieving the status of the
singleton object returns <tt class="constant">CAIRO_STATUS_NO_MEMORY</tt>
</p>
<i><span class="remark">
Is this going to apply to
<span class="type">cairo_surface_t</span> as well?
</span></i><i><span class="remark">
What about cairo_copy_path_data()? It's probably going to
have to return <tt class="constant">NULL</tt>.
</span></i>
</li>
<li><p>
Errors propagate from object to object. Setting a pattern
in an out-of-memory state as the source of a
<span class="type">cairo_t</span> puts the type into an error state.
</p></li>
</ul></div>
<i><span class="remark">Much of the above is not yet implemented at the time of
this writing</span></i><p>
A language binding could copy the C approach, and for a
language without exceptions, this is likely the right thing
to do. However, for a language with exceptions, exposing
a completely different style of error handling for cairo
would be strange. So, instead, status should be checked
after every call to cairo, and exceptions thrown as necessary.
</p>
<p>
One problem that can arise with this, in languages
where handling exceptions is mandatory (like Java), is that almost
every cairo function can result in a status being set,
usually because of an out-of-memory condition. This could make
cairo hard to use. To resolve this problem, let's classify then
cairo status codes:
</p>
<pre class="programlisting">
/* Memory */
CAIRO_STATUS_NO_MEMORY,
/* Programmer error */
CAIRO_STATUS_INVALID_RESTORE
CAIRO_STATUS_INVALID_POP_GROUP
CAIRO_STATUS_NO_CURRENT_POINT
CAIRO_STATUS_INVALID_MATRIX
CAIRO_STATUS_NO_TARGET_SURFACE
CAIRO_STATUS_INVALID_STRING
CAIRO_STATUS_SURFACE_FINISHED
CAIRO_STATUS_BAD_NESTING
/* Language binding implementation */
CAIRO_STATUS_NULL_POINTER
CAIRO_STATUS_INVALID_PATH_DATA
CAIRO_STATUS_SURFACE_TYPE_MISMATCH
/* Other */
CAIRO_STATUS_READ_ERROR
CAIRO_STATUS_WRITE_ERROR
</pre>
<p>
If we look at these, the
<tt class="constant">CAIRO_STATUS_NO_MEMORY</tt>
should map to the native out-of-memory exception, which could
happen at any point in any case. Most of the others indicate
programmer error, and handling them in user code would be
silly. These should be mapped into whatever the language uses
for assertion failures, rather than errors that are normally
handled. (In Java, a subclass of Error rather than Exception,
perhaps.) And <tt class="constant">CAIRO_STATUS_READ_ERROR</tt>,
and <tt class="constant">CAIRO_STATUS_WRITE_ERROR</tt> can occur
only in very specific places. (In fact, as described
in <a href="bindings-streams.html" title="Streams and File I/O">the section called “Streams and File I/O”</a>, these errors may be
mapped into the language's native I/O error types.)
So, there really aren't exceptions that the programmer must
handle at most points in the Cairo API.
</p>
</div>
<table class="navigation" width="100%" summary="Navigation footer" cellpadding="2" cellspacing="0"><tr valign="middle">
<td align="left"><a accesskey="p" href="bindings-streams.html"><b><< Streams and File I/O</b></a></td>
<td align="right"><a accesskey="n" href="bindings-patterns.html"><b>Patterns >></b></a></td>
</tr></table>
</body>
</html>
|