Merge fatalerror into utility.
[alexxy/gromacs.git] / src / gromacs / utility / exceptions.h
1 /*
2  *
3  *                This source code is part of
4  *
5  *                 G   R   O   M   A   C   S
6  *
7  *          GROningen MAchine for Chemical Simulations
8  *
9  * Written by David van der Spoel, Erik Lindahl, Berk Hess, and others.
10  * Copyright (c) 1991-2000, University of Groningen, The Netherlands.
11  * Copyright (c) 2001-2009, The GROMACS development team,
12  * check out http://www.gromacs.org for more information.
13  *
14  * This program is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public License
16  * as published by the Free Software Foundation; either version 2
17  * of the License, or (at your option) any later version.
18  *
19  * If you want to redistribute modifications, please consider that
20  * scientific software is very special. Version control is crucial -
21  * bugs must be traceable. We will be happy to consider code for
22  * inclusion in the official distribution, but derived work must not
23  * be called official GROMACS. Details are found in the README & COPYING
24  * files - if they are missing, get the official version at www.gromacs.org.
25  *
26  * To help us fund GROMACS development, we humbly ask that you cite
27  * the papers on the package - you can find them in the top README file.
28  *
29  * For more info, check our website at http://www.gromacs.org
30  */
31 /*! \file
32  * \brief
33  * Declares common exception classes for fatal error handling.
34  *
35  * \author Teemu Murtola <teemu.murtola@cbr.su.se>
36  * \inpublicapi
37  * \ingroup module_utility
38  */
39 #ifndef GMX_UTILITY_EXCEPTIONS_H
40 #define GMX_UTILITY_EXCEPTIONS_H
41
42 #include <exception>
43 #include <string>
44
45 #include <boost/exception/exception.hpp>
46 #include <boost/exception/info.hpp>
47 #include <boost/throw_exception.hpp>
48
49 namespace gmx
50 {
51
52 /*! \brief
53  * Stores a user-friendly explanation for the reason of an exception.
54  *
55  * Typically, should not be used directly, but through the GromacsException
56  * class: it is initialized by the constructor, and can be accessed with
57  * GromacsException::what().
58  *
59  * \inlibraryapi
60  */
61 typedef boost::error_info<struct errinfo_message_, std::string> errinfo_message;
62
63 /*! \addtopublicapi
64  * \{
65  */
66
67 /*! \brief
68  * Base class for all exception objects in Gromacs.
69  *
70  * Although boost recommends using virtual inheritance in exception hiearchies,
71  * it is not used here for two reasons:
72  * -# It is only useful when there is diamond inheritance, and that should
73  *    never occur in this exception hierarchy because this class is the only
74  *    instance of multiple inheritance (Gromacs programming guidelines prohibit
75  *    multiple inheritance from concrete classes, but it is unavoidable here
76  *    because of the design of boost::exception).
77  * -# Because the constructor takes an argument, virtual inheritance would
78  *    complicate any classes that inherit indirectly from this class.
79  *
80  * \ingroup module_utility
81  */
82 class GromacsException : public std::exception, public boost::exception
83 {
84     public:
85         /*! \brief
86          * Returns the reason string for the exception.
87          *
88          * The return value is the string that was passed to the constructor.
89          */
90         virtual const char *what() const throw();
91         /*! \brief
92          * Returns the error code corresponding to the exception type.
93          */
94         virtual int errorCode() const = 0;
95
96     protected:
97         /*! \brief
98          * Creates an exception object with the provided detailed reason.
99          *
100          * \param[in] reason Detailed reason for the exception.
101          */
102         explicit GromacsException(const std::string &reason);
103 };
104
105 /*! \brief
106  * Exception class for file I/O errors.
107  *
108  * \ingroup module_utility
109  */
110 class FileIOError : public GromacsException
111 {
112     public:
113         /*! \brief
114          * Creates an exception object with the provided detailed reason.
115          *
116          * \param[in] reason Detailed reason for the exception.
117          */
118         explicit FileIOError(const std::string &reason)
119             : GromacsException(reason) {}
120
121         virtual int errorCode() const;
122 };
123
124 /*! \brief
125  * Exception class for user input errors.
126  *
127  * Derived classes should be used to indicate the nature of the error instead
128  * of throwing this class directly.
129  *
130  * \ingroup module_utility
131  */
132 class UserInputError : public GromacsException
133 {
134     protected:
135         //! \copydoc FileIOError::FileIOError()
136         explicit UserInputError(const std::string &reason)
137             : GromacsException(reason) {}
138 };
139
140 /*! \brief
141  * Exception class for situations where user input cannot be parsed/understood.
142  *
143  * \ingroup module_utility
144  */
145 class InvalidInputError : public UserInputError
146 {
147     public:
148         //! \copydoc FileIOError::FileIOError()
149         explicit InvalidInputError(const std::string &reason)
150             : UserInputError(reason) {}
151
152         virtual int errorCode() const;
153 };
154
155 /*! \brief
156  * Exception class for situations where user input is inconsistent.
157  *
158  * \ingroup module_utility
159  */
160 class InconsistentInputError : public UserInputError
161 {
162     public:
163         //! \copydoc FileIOError::FileIOError()
164         explicit InconsistentInputError(const std::string &reason)
165             : UserInputError(reason) {}
166
167         virtual int errorCode() const;
168 };
169
170 /*! \brief
171  * Exception class for simulation instabilities.
172  *
173  * \ingroup module_utility
174  */
175 class SimulationInstabilityError : public GromacsException
176 {
177     public:
178         //! \copydoc FileIOError::FileIOError()
179         explicit SimulationInstabilityError(const std::string &reason)
180             : GromacsException(reason) {}
181
182         virtual int errorCode() const;
183 };
184
185 /*! \brief
186  * Exception class for internal errors.
187  *
188  * \ingroup module_utility
189  */
190 class InternalError : public GromacsException
191 {
192     public:
193         //! \copydoc FileIOError::FileIOError()
194         explicit InternalError(const std::string &reason)
195             : GromacsException(reason) {}
196
197         virtual int errorCode() const;
198 };
199
200 /*! \brief
201  * Exception class for incorrect use of an API.
202  *
203  * \ingroup module_utility
204  */
205 class APIError : public GromacsException
206 {
207     public:
208         //! \copydoc FileIOError::FileIOError()
209         explicit APIError(const std::string &reason)
210             : GromacsException(reason) {}
211
212         virtual int errorCode() const;
213 };
214
215 /*! \brief
216  * Exception class for use of an unimplemented feature.
217  *
218  * \ingroup module_utility
219  */
220 class NotImplementedError : public APIError
221 {
222     public:
223         //! \copydoc FileIOError::FileIOError()
224         explicit NotImplementedError(const std::string &reason)
225             : APIError(reason) {}
226
227         virtual int errorCode() const;
228 };
229
230
231 /*! \brief
232  * Macro for throwing an exception.
233  *
234  * \param[in] e    Exception object to throw.
235  *
236  * Using this macro instead of \c throw directly makes it possible to uniformly
237  * attach information into the exception objects.
238  * \p e should evaluate to an instance of an object derived from
239  * GromacsException.
240  *
241  * Basic usage:
242  * \code
243 if (value < 0)
244 {
245     GMX_THROW(InconsistentUserInput("Negative values not allowed for value"));
246 }
247  * \endcode
248  */
249 #define GMX_THROW(e) \
250     BOOST_THROW_EXCEPTION((e))
251
252 /*! \brief
253  * Formats a standard error message for reporting an error.
254  *
255  * Normal usage in Gromacs command-line programs is like this:
256  * \code
257 int main(int argc, char *argv[])
258 {
259     try
260     {
261         // The actual code for the program
262         return 0;
263     }
264     catch (const std::exception &ex)
265     {
266         fprintf(stderr, "%s", gmx::formatErrorMessage(ex).c_str());
267         return 1;
268     }
269 }
270  * \endcode
271  */
272 std::string formatErrorMessage(const std::exception &ex);
273
274 /*! \brief
275  * Converts an exception into a return code.
276  */
277 int translateException(const std::exception &ex);
278
279 /*!\}*/
280
281 } // namespace gmx
282
283 #endif