3 * This source code is part of
7 * GROningen MAchine for Chemical Simulations
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.
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.
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.
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.
29 * For more info, check our website at http://www.gromacs.org
33 * Declares common exception classes for fatal error handling.
35 * \author Teemu Murtola <teemu.murtola@cbr.su.se>
37 * \ingroup module_utility
39 #ifndef GMX_UTILITY_EXCEPTIONS_H
40 #define GMX_UTILITY_EXCEPTIONS_H
48 #include <boost/exception/errinfo_api_function.hpp>
49 #include <boost/exception/errinfo_errno.hpp>
50 #include <boost/exception/exception.hpp>
51 #include <boost/exception/info.hpp>
52 #include <boost/throw_exception.hpp>
58 * Stores a user-friendly explanation for the reason of an exception.
60 * Typically, should not be used directly, but through the GromacsException
61 * class: it is initialized by the constructor, and can be accessed with
62 * GromacsException::what().
66 typedef boost::error_info<struct errinfo_message_, std::string> errinfo_message;
73 * Base class for all exception objects in Gromacs.
75 * Although boost recommends using virtual inheritance in exception hiearchies,
76 * it is not used here for two reasons:
77 * -# It is only useful when there is diamond inheritance, and that should
78 * never occur in this exception hierarchy because this class is the only
79 * instance of multiple inheritance (Gromacs programming guidelines prohibit
80 * multiple inheritance from concrete classes, but it is unavoidable here
81 * because of the design of boost::exception).
82 * -# Because the constructor takes an argument, virtual inheritance would
83 * complicate any classes that inherit indirectly from this class.
85 * \ingroup module_utility
87 class GromacsException : public std::exception, public boost::exception
91 * Returns the reason string for the exception.
93 * The return value is the string that was passed to the constructor.
95 virtual const char *what() const throw();
97 * Returns the error code corresponding to the exception type.
99 virtual int errorCode() const = 0;
103 * Creates an exception object with the provided detailed reason.
105 * \param[in] reason Detailed reason for the exception.
107 explicit GromacsException(const std::string &reason);
111 * Exception class for file I/O errors.
113 * \ingroup module_utility
115 class FileIOError : public GromacsException
119 * Creates an exception object with the provided detailed reason.
121 * \param[in] reason Detailed reason for the exception.
123 explicit FileIOError(const std::string &reason)
124 : GromacsException(reason) {}
126 virtual int errorCode() const;
130 * Exception class for user input errors.
132 * Derived classes should be used to indicate the nature of the error instead
133 * of throwing this class directly.
135 * \ingroup module_utility
137 class UserInputError : public GromacsException
140 //! \copydoc FileIOError::FileIOError()
141 explicit UserInputError(const std::string &reason)
142 : GromacsException(reason) {}
146 * Exception class for situations where user input cannot be parsed/understood.
148 * \ingroup module_utility
150 class InvalidInputError : public UserInputError
153 //! \copydoc FileIOError::FileIOError()
154 explicit InvalidInputError(const std::string &reason)
155 : UserInputError(reason) {}
157 virtual int errorCode() const;
161 * Exception class for situations where user input is inconsistent.
163 * \ingroup module_utility
165 class InconsistentInputError : public UserInputError
168 //! \copydoc FileIOError::FileIOError()
169 explicit InconsistentInputError(const std::string &reason)
170 : UserInputError(reason) {}
172 virtual int errorCode() const;
176 * Exception class for simulation instabilities.
178 * \ingroup module_utility
180 class SimulationInstabilityError : public GromacsException
183 //! \copydoc FileIOError::FileIOError()
184 explicit SimulationInstabilityError(const std::string &reason)
185 : GromacsException(reason) {}
187 virtual int errorCode() const;
191 * Exception class for internal errors.
193 * \ingroup module_utility
195 class InternalError : public GromacsException
198 //! \copydoc FileIOError::FileIOError()
199 explicit InternalError(const std::string &reason)
200 : GromacsException(reason) {}
202 virtual int errorCode() const;
206 * Exception class for incorrect use of an API.
208 * \ingroup module_utility
210 class APIError : public GromacsException
213 //! \copydoc FileIOError::FileIOError()
214 explicit APIError(const std::string &reason)
215 : GromacsException(reason) {}
217 virtual int errorCode() const;
221 * Exception class for use of an unimplemented feature.
223 * \ingroup module_utility
225 class NotImplementedError : public APIError
228 //! \copydoc FileIOError::FileIOError()
229 explicit NotImplementedError(const std::string &reason)
230 : APIError(reason) {}
232 virtual int errorCode() const;
237 * Macro for throwing an exception.
239 * \param[in] e Exception object to throw.
241 * Using this macro instead of \c throw directly makes it possible to uniformly
242 * attach information into the exception objects.
243 * \p e should evaluate to an instance of an object derived from
250 GMX_THROW(InconsistentUserInput("Negative values not allowed for value"));
254 #define GMX_THROW(e) \
255 BOOST_THROW_EXCEPTION((e))
258 * Macro for throwing an exception based on errno.
260 * \param[in] e Exception object to throw.
261 * \param[in] syscall Name of the syscall that returned the error.
262 * \param[in] err errno value returned by the syscall.
264 * This macro provides a convenience interface for throwing an exception to
265 * report an error based on a errno value. In addition to adding the necessary
266 * information to the exception object, the macro also ensures that \p errno is
267 * evaluated before, e.g., the constructor of \p e may call other functions
268 * that could overwrite the errno value.
269 * \p e should evaluate to an instance of an object derived from
272 * Typical usage (note that gmx::File wraps this particular case):
274 FILE *fp = fopen("filename.txt", "r");
277 GMX_THROW(FileIOError("Could not open file"), "fopen", errno);
281 #define GMX_THROW_WITH_ERRNO(e, syscall, err) \
283 int stored_errno_ = (err); \
284 GMX_THROW((e) << boost::errinfo_errno(stored_errno_) \
285 << boost::errinfo_api_function(syscall)); \
289 * Formats a standard fatal error message for reporting an exception.
291 * Does not throw. If memory allocation fails or some other error occurs
292 * while formatting the error, tries to print a reasonable alternative message.
294 * Normal usage in Gromacs command-line programs is like this:
296 int main(int argc, char *argv[])
298 gmx::ProgramInfo::init(argc, argv);
301 // The actual code for the program
304 catch (const std::exception &ex)
306 gmx::printFatalErrorMessage(stderr, ex);
312 void printFatalErrorMessage(FILE *fp, const std::exception &ex);
315 * Converts an exception into a return code.
317 int translateException(const std::exception &ex);
322 /*! \libinternal \brief
323 * Macro for catching exceptions at C++ -> C boundary.
325 * This macro is intended for uniform handling of exceptions when C++ code is
326 * called from C code within Gromacs. Since most existing code is written
327 * using the assumption that fatal errors terminate the program, this macro
328 * implements this behavior for exceptions. It should only be used in cases
329 * where the error cannot be propagated upwards using return values or such.
331 * Having this as a macro instead of having the same code in each place makes
332 * it easy to 1) find all such locations in the code, and 2) change the exact
333 * behavior if needed.
341 GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
346 #define GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR \
347 catch (const std::exception &ex) { \
348 ::gmx::printFatalErrorMessage(stderr, ex); \