Remove cycle suppression
[gromacs.git] / docs / dev-manual / error-handling.rst
blobb56bb27ca2530196e5b846345e4b86381940c4ce
1 .. _error handling:
3 Error handling
4 ==============
6 To make |Gromacs| behave like a proper library, we need to change the
7 way errors etc. are handled. Basically, the library should not print
8 out anything to stdio/stderr unless it is part of the API
9 specification, and even then, there should be a way for the user to
10 suppress the output. Also, the library should normally not terminate
11 the program without the user having control over this. There are
12 different types of errors, which also affects the handling. Different
13 cases are discussed separately below, split by the way they are
14 handled. These guidelines are starting to take their final form,
15 although details may still change.
17 * For programming errors, i.e., errors that should never occur if the
18   program is correctly written, it's acceptable to assert and
19   terminate the program. This applies to both errors in the library
20   and errors in user code or user input that calls the library.
21   Older code tends to still use ``assert()`` calls, but new
22   code should prefer more expressive functionality such as
23   ``GMX_RELEASE_ASSERT()``. This version of the macro will result
24   in asserts that are still present when the build type is Release,
25   which is what we want by default. In performance-sensitive parts
26   of the code, it is acceptable to rather use ``GMX_ASSERT()`` to
27   avoid the performance penalty of a branch when the code is compiled
28   for production use. By default, Jenkins builds the RelWithAssert
29   build type.
30 * For some errors it might be feasible to recover gracefully and
31   continue execution. In this case, your APIs should be defined
32   so that the API-user/programmer does not have to check separately
33   whether the problem was due to a programming error, but it's
34   better to e.g. use exceptions for recoverable errors and
35   asserts for programming errors.
36 * Exceptions should only be used for unexpected errors, e.g., out of
37   memory or file system IO errors. As a general guideline, incorrect
38   user input should not produce an untrapped exception resulting
39   in execution termination telling the user an exception occured.
40   Instead, you should catch exceptions in an earlier stack frame,
41   make a suitable decision about diagnostic messages, and then
42   decide how execution should be terminated.
43 * There is a global list of possible exceptions in
44   ``src/gromacs/utility/exceptions.h``, and the library should throw
45   one of these when it fails, possibly providing a more detailed
46   description of the reason for the failure. The types of exceptions
47   can be extended, and currently include:
49   - Out of memory (e.g. ``std::bad_alloc``)
51   - File I/O error (e.g. not found)
53   - Invalid user input (could not be understood)
55   - Inconsistent user input (parsed correctly, but has internal conflicts)
57   - Simulation instability
59   - Invalid API call/value/internal error (an assertion might also be used in such cases)
61   - In the internals of a module called from code that is not
62     exception safe, you can use exceptions for error handling, but
63     avoid propagating them to caller code.
65 * Avoid using exceptions to propagate errors across regions that start
66   or join threads with OpenMP, since OpenMP cannot make guarantees about
67   whether exceptions are caught or if the program will crash.
68   Currently we catch all exceptions before we leave an OpenMP threaded region.
69   If you throw an exception, make sure that it is caught and handled appropriately
70   in the same thread/OpenMP section.
71 * There are also cases where a library routine wants to report a
72   warning or a non-fatal error, but is still able to continue
73   processing. In this case you should try to collect all issues and
74   report and report them (similar to what grompp does with notes, warnings
75   and errors) instead of just returning the first error. It is irritating
76   to users if they fix the reported error, but then they keep getting
77   a new error message every time the rerun the program.
78 * A function should not fail as part of its normal operation.
79   However, doing nothing can be considered normal operation. A function
80   accessing data should typically also be callable when no such data is
81   available, but still return through normal means. If the failure is not
82   normal, it is OK to rather throw an exception.
84 For coding guidelines to make this all work, see :ref:`implementing exceptions`.