1@c Copyright (C) 1996-2019 John W. Eaton
2@c
3@c This file is part of Octave.
4@c
5@c Octave is free software: you can redistribute it and/or modify it
6@c under the terms of the GNU General Public License as published by
7@c the Free Software Foundation, either version 3 of the License, or
8@c (at your option) any later version.
9@c
10@c Octave is distributed in the hope that it will be useful, but
11@c WITHOUT ANY WARRANTY; without even the implied warranty of
12@c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13@c GNU General Public License for more details.
14@c
15@c You should have received a copy of the GNU General Public License
16@c along with Octave; see the file COPYING.  If not, see
17@c <https://www.gnu.org/licenses/>.
18
19@node Errors and Warnings
20@chapter Errors and Warnings
21
22Octave includes several functions for printing error and warning
23messages.  When you write functions that need to take special action
24when they encounter abnormal conditions, you should print the error
25messages using the functions described in this chapter.
26
27Since many of Octave's functions use these functions, it is also useful
28to understand them, so that errors and warnings can be handled.
29
30@menu
31* Handling Errors::
32* Handling Warnings::
33@end menu
34
35@node Handling Errors
36@section Handling Errors
37
38An error is something that occurs when a program is in a state where
39it doesn't make sense to continue.  An example is when a function is
40called with too few input arguments.  In this situation the function
41should abort with an error message informing the user of the lacking
42input arguments.
43
44Since an error can occur during the evaluation of a program, it is
45very convenient to be able to detect that an error occurred, so that
46the error can be fixed.  This is possible with the @code{try} statement
47described in @ref{The try Statement}.
48
49@menu
50* Raising Errors::
51* Catching Errors::
52* Recovering From Errors::
53@end menu
54
55@node Raising Errors
56@subsection Raising Errors
57
58The most common use of errors is for checking input arguments to
59functions.  The following example calls the @code{error} function if
60the function @code{f} is called without any input arguments.
61
62@example
63@group
64function f (arg1)
65  if (nargin == 0)
66    error ("not enough input arguments");
67  endif
68endfunction
69@end group
70@end example
71
72When the @code{error} function is called, it prints the given message
73and returns to the Octave prompt.  This means that no code following
74a call to @code{error} will be executed.
75
76It is also possible to assign an identification string to an error.
77If an error has such an ID the user can catch this error
78as will be described in the next section.  To assign an ID to an error,
79simply call @code{error} with two string arguments, where the first
80is the identification string, and the second is the actual error.  Note
81that error IDs are in the format @qcode{"NAMESPACE:ERROR-NAME"}.  The namespace
82@qcode{"Octave"} is used for Octave's own errors.  Any other string is
83available as a namespace for user's own errors.
84
85@DOCSTRING(error)
86
87Since it is common to use errors when there is something wrong with
88the input to a function, Octave supports functions to simplify such code.
89When the @code{print_usage} function is called, it reads the help text
90of the function calling @code{print_usage}, and presents a useful error.
91If the help text is written in Texinfo it is possible to present an
92error message that only contains the function prototypes as described
93by the @code{@@deftypefn} parts of the help text.  When the help text
94isn't written in Texinfo, the error message contains the entire help
95message.
96
97Consider the following function.
98
99@example
100@group
101## -*- texinfo -*-
102## @@deftypefn @{@} f (@@var@{arg1@})
103## Function help text goes here@dots{}
104## @@end deftypefn
105function f (arg1)
106  if (nargin == 0)
107    print_usage ();
108  endif
109endfunction
110@end group
111@end example
112
113@noindent
114When it is called with no input arguments it produces the following
115error.
116
117@example
118@group
119f ()
120
121@print{}  error: Invalid call to f.  Correct usage is:
122@print{}
123@print{}   -- f (ARG1)
124@print{}
125@print{}
126@print{}  Additional help for built-in functions and operators is
127@print{}  available in the online version of the manual.  Use the command
128@print{}  'doc <topic>' to search the manual index.
129@print{}
130@print{}  Help and information about Octave is also available on the WWW
131@print{}  at https://www.octave.org and via the help@@octave.org
132@print{}  mailing list.
133@end group
134@end example
135
136@DOCSTRING(print_usage)
137
138@DOCSTRING(beep)
139
140@DOCSTRING(beep_on_error)
141
142@node Catching Errors
143@subsection Catching Errors
144
145When an error occurs, it can be detected and handled using the
146@code{try} statement as described in @ref{The try Statement}.
147As an example, the following piece of code counts the number of errors
148that occurs during a @code{for} loop.
149
150@example
151@group
152number_of_errors = 0;
153for n = 1:100
154  try
155    @dots{}
156  catch
157    number_of_errors++;
158  end_try_catch
159endfor
160@end group
161@end example
162
163The above example treats all errors the same.  In many situations it
164can however be necessary to discriminate between errors, and take
165different actions depending on the error.  The @code{lasterror}
166function returns a structure containing information about the last
167error that occurred.  As an example, the code above could be changed
168to count the number of errors related to the @samp{*} operator.
169
170@example
171@group
172number_of_errors = 0;
173for n = 1:100
174  try
175    @dots{}
176  catch
177    msg = lasterror.message;
178    if (strfind (msg, "operator *"))
179      number_of_errors++;
180    endif
181  end_try_catch
182endfor
183@end group
184@end example
185
186@noindent
187Alternatively, the output of the @code{lasterror} function can be found
188in a variable indicated immediately after the @code{catch} keyword, as
189in the example below showing how to redirect an error as a warning:
190
191@example
192@group
193try
194  @dots{}
195catch err
196  warning(err.identifier, err.message);
197  @dots{}
198end_try_catch
199@end group
200@end example
201
202@DOCSTRING(lasterror)
203
204@DOCSTRING(lasterr)
205
206The next example counts indexing errors.  The errors are caught using the
207field identifier of the structure returned by the function @code{lasterror}.
208
209@example
210@group
211number_of_errors = 0;
212for n = 1:100
213  try
214    @dots{}
215  catch
216    id = lasterror.identifier;
217    if (strcmp (id, "Octave:invalid-indexing"))
218      number_of_errors++;
219    endif
220  end_try_catch
221endfor
222@end group
223@end example
224
225The functions distributed with Octave can issue one of the following
226errors.
227
228@DOCSTRING(error_ids)
229
230When an error has been handled it is possible to raise it again.  This
231can be useful when an error needs to be detected, but the program should
232still abort.  This is possible using the @code{rethrow} function.  The
233previous example can now be changed to count the number of errors
234related to the @samp{*} operator, but still abort if another kind of
235error occurs.
236
237@example
238@group
239number_of_errors = 0;
240for n = 1:100
241  try
242    @dots{}
243  catch
244    msg = lasterror.message;
245    if (strfind (msg, "operator *"))
246      number_of_errors++;
247    else
248      rethrow (lasterror);
249    endif
250  end_try_catch
251endfor
252@end group
253@end example
254
255@DOCSTRING(rethrow)
256
257@c FIXME: I have no idea what the rest of the functions are used for...
258
259@DOCSTRING(errno)
260
261@DOCSTRING(errno_list)
262
263@node Recovering From Errors
264@subsection Recovering From Errors
265
266Octave provides several ways of recovering from errors.  There are
267@code{try}/@code{catch} blocks,
268@code{unwind_protect}/@code{unwind_protect_cleanup} blocks,
269and finally the @code{onCleanup} command.
270
271The @code{onCleanup} command associates an ordinary Octave variable (the
272trigger) with an arbitrary function (the action).  Whenever the Octave variable
273ceases to exist---whether due to a function return, an error, or simply because
274the variable has been removed with @code{clear}---then the assigned function
275is executed.
276
277The function can do anything necessary for cleanup such as closing open file
278handles, printing an error message, or restoring global variables to their
279initial values.  The last example is a very convenient idiom for Octave code.
280For example:
281
282@example
283@group
284function rand42
285  old_state = rand ("state");
286  restore_state = onCleanup (@@() rand ("state", old_state));
287  rand ("state", 42);
288  @dots{}
289endfunction  # rand generator state restored by onCleanup
290@end group
291@end example
292
293@DOCSTRING(onCleanup)
294
295@node Handling Warnings
296@section Handling Warnings
297
298Like an error, a warning is issued when something unexpected happens.
299Unlike an error, a warning doesn't abort the currently running program.
300A simple example of a warning is when a number is divided by zero.  In
301this case Octave will issue a warning and assign the value @code{Inf}
302to the result.
303
304@example
305@group
306a = 1/0
307     @print{} warning: division by zero
308     @result{} a = Inf
309@end group
310@end example
311
312@menu
313* Issuing Warnings::
314* Enabling and Disabling Warnings::
315@end menu
316
317@node Issuing Warnings
318@subsection Issuing Warnings
319
320It is possible to issue warnings from any code using the @code{warning}
321function.  In its most simple form, the @code{warning} function takes a
322string describing the warning as its input argument.  As an example,
323the following code controls if the variable @samp{a} is non-negative,
324and if not issues a warning and sets @samp{a} to zero.
325
326@example
327@group
328a = -1;
329if (a < 0)
330  warning ("'a' must be non-negative.  Setting 'a' to zero.");
331  a = 0;
332endif
333     @print{} 'a' must be non-negative.  Setting 'a' to zero.
334@end group
335@end example
336
337Since warnings aren't fatal to a running program, it is not possible
338to catch a warning using the @code{try} statement or something similar.
339It is however possible to access the last warning as a string using the
340@code{lastwarn} function.
341
342It is also possible to assign an identification string to a warning.
343If a warning has such an ID the user can enable and disable this warning
344as will be described in the next section.  To assign an ID to a warning,
345simply call @code{warning} with two string arguments, where the first
346is the identification string, and the second is the actual warning.  Note
347that warning IDs are in the format @qcode{"NAMESPACE:WARNING-NAME"}.  The
348namespace @qcode{"Octave"} is used for Octave's own warnings.  Any other string
349is available as a namespace for user's own warnings.
350
351@DOCSTRING(warning)
352
353@DOCSTRING(lastwarn)
354
355The functions distributed with Octave can issue one of the following
356warnings.
357
358@DOCSTRING(warning_ids)
359
360@node Enabling and Disabling Warnings
361@subsection Enabling and Disabling Warnings
362
363The @code{warning} function also allows you to control which warnings
364are actually printed to the screen.  If the @code{warning} function
365is called with a string argument that is either @qcode{"on"} or @qcode{"off"}
366all warnings will be enabled or disabled.
367
368It is also possible to enable and disable individual warnings through
369their string identifications.  The following code will issue a warning
370
371@example
372@group
373warning ("example:non-negative-variable",
374         "'a' must be non-negative.  Setting 'a' to zero.");
375@end group
376@end example
377
378@noindent
379while the following won't issue a warning
380
381@example
382@group
383warning ("off", "example:non-negative-variable");
384warning ("example:non-negative-variable",
385         "'a' must be non-negative.  Setting 'a' to zero.");
386@end group
387@end example
388