1.. index:: error handling
2
3**************
4Error Handling
5**************
6
7This chapter describes the way that GSL functions report and handle
8errors.  By examining the status information returned by every function
9you can determine whether it succeeded or failed, and if it failed you
10can find out what the precise cause of failure was.  You can also define
11your own error handling functions to modify the default behavior of the
12library.
13
14The functions described in this section are declared in the header file
15:file:`gsl_errno.h`.
16
17Error Reporting
18===============
19
20The library follows the thread-safe error reporting conventions of the
21POSIX Threads library.  Functions return a non-zero error code to
22indicate an error and :code:`0` to indicate success::
23
24    int status = gsl_function (...)
25
26    if (status) { /* an error occurred */
27      .....
28      /* status value specifies the type of error */
29    }
30
31The routines report an error whenever they cannot perform the task
32requested of them.  For example, a root-finding function would return a
33non-zero error code if could not converge to the requested accuracy, or
34exceeded a limit on the number of iterations.  Situations like this are
35a normal occurrence when using any mathematical library and you should
36check the return status of the functions that you call.
37
38Whenever a routine reports an error the return value specifies the type
39of error.  The return value is analogous to the value of the variable
40:code:`errno` in the C library.  The caller can examine the return code
41and decide what action to take, including ignoring the error if it is
42not considered serious.
43
44In addition to reporting errors by return codes the library also has an
45error handler function :func:`gsl_error`.  This function is called by
46other library functions when they report an error, just before they
47return to the caller.  The default behavior of the error handler is to
48print a message and abort the program::
49
50    gsl: file.c:67: ERROR: invalid argument supplied by user
51    Default GSL error handler invoked.
52    Aborted
53
54The purpose of the :func:`gsl_error` handler is to provide a function
55where a breakpoint can be set that will catch library errors when
56running under the debugger.  It is not intended for use in production
57programs, which should handle any errors using the return codes.
58
59.. index::
60   single: error codes, reserved
61
62Error Codes
63===========
64
65The error code numbers returned by library functions are defined in
66the file :file:`gsl_errno.h`.  They all have the prefix :code:`GSL_` and
67expand to non-zero constant integer values. Error codes above 1024 are
68reserved for applications, and are not used by the library.  Many of
69the error codes use the same base name as the corresponding error code
70in the C library.  Here are some of the most common error codes,
71
72.. index::
73   single: error codes
74
75.. var:: int GSL_EDOM
76
77   Domain error; used by mathematical functions when an argument value does
78   not fall into the domain over which the function is defined (like
79   :data:`EDOM` in the C library)
80
81.. var:: int GSL_ERANGE
82
83   Range error; used by mathematical functions when the result value is not
84   representable because of overflow or underflow (like :data:`ERANGE` in the C
85   library)
86
87.. var:: int GSL_ENOMEM
88
89   No memory available.  The system cannot allocate more virtual memory
90   because its capacity is full (like :data:`ENOMEM` in the C library).  This error
91   is reported when a GSL routine encounters problems when trying to
92   allocate memory with :func:`malloc`.
93
94.. var:: int GSL_EINVAL
95
96   Invalid argument.  This is used to indicate various kinds of problems
97   with passing the wrong argument to a library function (like :data:`EINVAL` in the C
98   library).
99
100The error codes can be converted into an error message using the
101function :func:`gsl_strerror`.
102
103.. function:: const char * gsl_strerror (const int gsl_errno)
104
105   This function returns a pointer to a string describing the error code
106   :data:`gsl_errno`. For example::
107
108     printf ("error: %s\n", gsl_strerror (status));
109
110   would print an error message like :code:`error: output range error` for a
111   status value of :data:`GSL_ERANGE`.
112
113.. index:: error handlers
114
115Error Handlers
116==============
117
118The default behavior of the GSL error handler is to print a short
119message and call :func:`abort`.  When this default is in use programs
120will stop with a core-dump whenever a library routine reports an error.
121This is intended as a fail-safe default for programs which do not check
122the return status of library routines (we don't encourage you to write
123programs this way).
124
125If you turn off the default error handler it is your responsibility to
126check the return values of routines and handle them yourself.  You can
127also customize the error behavior by providing a new error handler. For
128example, an alternative error handler could log all errors to a file,
129ignore certain error conditions (such as underflows), or start the
130debugger and attach it to the current process when an error occurs.
131
132All GSL error handlers have the type :code:`gsl_error_handler_t`, which is
133defined in :file:`gsl_errno.h`,
134
135.. type:: gsl_error_handler_t
136
137   This is the type of GSL error handler functions.  An error handler will
138   be passed four arguments which specify the reason for the error (a
139   string), the name of the source file in which it occurred (also a
140   string), the line number in that file (an integer) and the error number
141   (an integer).  The source file and line number are set at compile time
142   using the :code:`__FILE__` and :code:`__LINE__` directives in the
143   preprocessor.  An error handler function returns type :code:`void`.
144   Error handler functions should be defined like this::
145
146     void handler (const char * reason,
147                   const char * file,
148                   int line,
149                   int gsl_errno)
150
151To request the use of your own error handler you need to call the
152function :func:`gsl_set_error_handler` which is also declared in
153:file:`gsl_errno.h`,
154
155.. function:: gsl_error_handler_t * gsl_set_error_handler (gsl_error_handler_t * new_handler)
156
157   This function sets a new error handler, :data:`new_handler`, for the GSL
158   library routines.  The previous handler is returned (so that you can
159   restore it later).  Note that the pointer to a user defined error
160   handler function is stored in a static variable, so there can be only
161   one error handler per program.  This function should be not be used in
162   multi-threaded programs except to set up a program-wide error handler
163   from a master thread.  The following example shows how to set and
164   restore a new error handler::
165
166     /* save original handler, install new handler */
167     old_handler = gsl_set_error_handler (&my_handler);
168
169     /* code uses new handler */
170     .....
171
172     /* restore original handler */
173     gsl_set_error_handler (old_handler);
174
175   To use the default behavior (:func:`abort` on error) set the error
176   handler to :code:`NULL`::
177
178     old_handler = gsl_set_error_handler (NULL);
179
180.. function:: gsl_error_handler_t * gsl_set_error_handler_off ()
181
182   This function turns off the error handler by defining an error handler
183   which does nothing. This will cause the program to continue after any
184   error, so the return values from any library routines must be checked.
185   This is the recommended behavior for production programs.  The previous
186   handler is returned (so that you can restore it later).
187
188The error behavior can be changed for specific applications by
189recompiling the library with a customized definition of the
190:code:`GSL_ERROR` macro in the file :file:`gsl_errno.h`.
191
192.. index:: error handling macros
193
194Using GSL error reporting in your own functions
195===============================================
196
197If you are writing numerical functions in a program which also uses GSL
198code you may find it convenient to adopt the same error reporting
199conventions as in the library.
200
201To report an error you need to call the function :func:`gsl_error` with a
202string describing the error and then return an appropriate error code
203from :file:`gsl_errno.h`, or a special value, such as :code:`NaN`.  For
204convenience the file :file:`gsl_errno.h` defines two macros which carry
205out these steps:
206
207.. macro:: GSL_ERROR (reason, gsl_errno)
208
209   This macro reports an error using the GSL conventions and returns a
210   status value of :code:`gsl_errno`.  It expands to the following code fragment::
211
212     gsl_error (reason, __FILE__, __LINE__, gsl_errno);
213     return gsl_errno;
214
215   The macro definition in :file:`gsl_errno.h` actually wraps the code
216   in a :code:`do { ... } while (0)` block to prevent possible
217   parsing problems.
218
219Here is an example of how the macro could be used to report that a
220routine did not achieve a requested tolerance.  To report the error the
221routine needs to return the error code :code:`GSL_ETOL`::
222
223    if (residual > tolerance)
224      {
225        GSL_ERROR("residual exceeds tolerance", GSL_ETOL);
226      }
227
228.. macro:: GSL_ERROR_VAL (reason, gsl_errno, value)
229
230   This macro is the same as :code:`GSL_ERROR` but returns a user-defined
231   value of :data:`value` instead of an error code.  It can be used for
232   mathematical functions that return a floating point value.
233
234The following example shows how to return a :code:`NaN` at a mathematical
235singularity using the :code:`GSL_ERROR_VAL` macro::
236
237    if (x == 0)
238      {
239        GSL_ERROR_VAL("argument lies on singularity", GSL_ERANGE, GSL_NAN);
240      }
241
242
243Examples
244========
245
246Here is an example of some code which checks the return value of a
247function where an error might be reported::
248
249    #include <stdio.h>
250    #include <gsl/gsl_errno.h>
251    #include <gsl/gsl_fft_complex.h>
252
253    ...
254      int status;
255      size_t n = 37;
256
257      gsl_set_error_handler_off();
258
259      status = gsl_fft_complex_radix2_forward (data, stride, n);
260
261      if (status) {
262        if (status == GSL_EINVAL) {
263           fprintf (stderr, "invalid argument, n=%d\n", n);
264        } else {
265           fprintf (stderr, "failed, gsl_errno=%d\n", status);
266        }
267        exit (-1);
268      }
269    ...
270
271The function :func:`gsl_fft_complex_radix2_forward` only accepts integer lengths
272which are a power of two.  If the variable :code:`n` is not a power of
273two then the call to the library function will return :code:`GSL_EINVAL`,
274indicating that the length argument is invalid.  The function call to
275:func:`gsl_set_error_handler_off` stops the default error handler from
276aborting the program.  The :code:`else` clause catches any other possible
277errors.
278
279