File: error_handling.html

package info (click to toggle)
erlang-doc-html 1%3A11.b.2-1
  • links: PTS
  • area: main
  • in suites: etch, etch-m68k
  • size: 23,284 kB
  • ctags: 10,724
  • sloc: erlang: 505; ansic: 323; makefile: 62; perl: 61; sh: 45
file content (200 lines) | stat: -rw-r--r-- 8,069 bytes parent folder | download
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<!-- This document was generated using DocBuilder 3.3.3 -->
<HTML>
<HEAD>
  <TITLE>Error handling</TITLE>
  <SCRIPT type="text/javascript" src="../../../../doc/erlresolvelinks.js">
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#FF00FF"
      ALINK="#FF0000">
<CENTER>
<A HREF="http://www.erlang.se"><IMG BORDER=0 ALT="[Ericsson AB]" SRC="min_head.gif"></A>
</CENTER>
<A NAME="4"><!-- Empty --></A>
<H2>4 Error handling</H2>
<A NAME="4.1"><!-- Empty --></A>
<H3>4.1  Strategy </H3>

<P> On a conceptual level starting a database connection using the
Erlang ODBC API is a basic client server application. The client
process uses the API to start and communicate with the server
process that manages the connection. The strategy of the Erlang
ODBC application is that programming faults in the application
itself will cause the connection process to terminate
abnormally.(When a process terminates abnormally its supervisor
will log relevant error reports.) Calls to API functions during or
after termination of the connection process, will return <CODE> {error, connection_closed}</CODE>. Contextual errors on the other
hand will not terminate the connection it will only return
<CODE>{error, Reason} </CODE> to the client, where <CODE>Reason</CODE> may be
any erlang term.
<A NAME="4.1.1"><!-- Empty --></A>
<H4>4.1.1  Clients </H4>

<P>The connection is associated with the process that created it
and can only be accessed through it. The reason for this is to
preserve the semantics of result sets and transactions when
select_count/[2,3] is called or auto_commit is turned off.
Attempts to use the connection from another process will
fail. This will not effect the connection. On the other hand, if
the client process dies the connection will be terminated.
<A NAME="4.1.2"><!-- Empty --></A>
<H4>4.1.2  Timeouts </H4>

<P> All request made by the client to the connection are
        synchronous. If the timeout is used and expires the client
        process will exit with reason timeout. Proably the right thing
        to do is let the client die and perhaps be restarted by its
        supervisor. But if the client chooses to catch this timeout,
        it is a good idea to wait a little while before trying
        again. If there are too many consecutive timeouts that are
        caught the connection process will conclude that there is
        something radically wrong and terminate the connection.
<A NAME="4.1.3"><!-- Empty --></A>
<H4>4.1.3  Gaurds </H4>

<P>All API-functions are guarded and if you pass an argument of
the wrong type a runtime error will occur. All input parameters
to internal functions are trusted to be correct. It is a good
programming practise to only distrust input from truly external
sources. You are not supposed to catch these errors, it will
only make the code very messy and much more complex, which
introduces more bugs and in the worst case also covers up the
actual faults. Put your effort on testing instead, you should
trust your own input.
<A NAME="4.2"><!-- Empty --></A>
<H3>4.2  The whole picture </H3>

<P> As the Erlang ODBC application relies on third party products
and communicates with a database that proably runs on an other
computer in the network there are plenty of things that might go
wrong. To fully understand the things that might happen it
facilitate to know the design of the Erlang ODBC application,
hence here follows a short description of the current design.

<P>
<TABLE CELLPADDING=4>
  <TR>
    <TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
    <TD>

<P>Please note that design is something, that not
necessarily will, but might change in future releases. While the
semantics of the API will not change as it is independent of the
implementation.    </TD>
  </TR>
</TABLE>

<P>
<CENTER>
<IMG ALT="odbc_app_arc" SRC="odbc_app_arc.gif"><BR>
<EM>Architecture of the Erlang odbc application</EM>

</CENTER>

<P> When you do application:start(odbc) the only thing that
happens is that a supervisor process is started. For each call
to the API function connect/2 a process is spawned and added as
a child to the Erlang ODBC supervisor. The supervisors only
tasks are to provide error-log reports, if a child process should
die abnormally, and the possibility to do a code change. Only
the client process has the knowledge to decide if this
connection managing process should be restarted.

<P>The erlang connection process spawned by connect/2, will open a
port to a c-process that handles the communication with the
database through Microsoft's ODBC API. The erlang port will be
kept open for exit signal propagation, if something goes wrong
in the c-process and it exits we want know as mush as possible
about the reason. The main communication with the c-process is
done through sockets. The C-process consists of two threads,
the supervisor thread and the database handler thread. The
supervisor thread checks for shutdown messages on the supervisor
socket and the database handler thread receives requests and sends
answers on the database socket. If the database thread seems to
hang on some database call, the erlang control process will send
a shutdown message on the supervisor socket, in this case the
c-process will exit. If the c-process crashes/exits it will
bring the erlang-process down too and vice versa i.e. the
connection is terminated.

<P>
<TABLE CELLPADDING=4>
  <TR>
    <TD VALIGN=TOP><IMG ALT="Note!" SRC="note.gif"></TD>
    <TD>

<P> The function connect/2 will start the odbc application if
        that is not already done. In this case a supervisor information
        log will be produced stating that the odbc application was started
        as a temporary application. It is really the responsibility of the
        application that uses the API too make sure it is started in the
        desired way.    </TD>
  </TR>
</TABLE>
<A NAME="4.2.1"><!-- Empty --></A>
<H4>4.2.1  Error types</H4>

<P>The types of errors that may occur can be divide into the
        following categories.

<P>
<UL>

<LI>
Configuration problems - Everything from that the
         database was not set up right to that the c-program that
         should be run through the erlang port was not compiled for
         your platform.
        
</LI>


<LI>
Errors discovered by the ODBC driver - If calls to the
         ODBC-driver fails due to circumstances that can not be
         controlled by the Erlang ODBC application programmer, an
         error string will be dug up from the driver. This string
         will be the <CODE>Reason</CODE> in the <CODE>{error, Reason} </CODE>
         return value. How good this error message is will of course
         be driver dependent. Examples of such circumstances are
         trying to insert the same key twice, invalid SQL-queries and
         that the database has gone off line.
        
</LI>


<LI>
 Connection termination - If a connection is terminated
         in an abnormal way, or if you try to use a connection that
         you have already terminated in a normal way by calling
         disconnect/1, the return value will be<CODE> {error,
         connection_closed}</CODE>. A connection could end abnormally
         because of an programming error in the Erlang ODBC
         application, but also if the ODBC driver crashes.
        
</LI>


<LI>
Contextual errors - If API functions are used in the
         wrong context, the <CODE> Reason</CODE> in the error tuple will
         be a descriptive atom. For instance if you try to call the
         function <CODE> last/[1,2] </CODE> without first calling <CODE>         select_count/[2,3] </CODE> to associate a result set with the
         connection. If the ODBC-driver does not support some
         functions, or if you disabled some functionality for a
         connection and then try to use it.
        
</LI>


</UL>
<CENTER>
<HR>
<SMALL>
Copyright &copy; 1991-2006
<A HREF="http://www.erlang.se">Ericsson AB</A><BR>
</SMALL>
</CENTER>
</BODY>
</HTML>