Index: kernel/include/IMP/DecoratorBase.h =================================================================== --- kernel/include/IMP/DecoratorBase.h (revision 388) +++ kernel/include/IMP/DecoratorBase.h (working copy) @@ -59,7 +59,8 @@ IMP_check(D::has_required_attributes(p), "Attempting to cast a Particle which does not have" " some required attributes", - InvalidStateException()); + InvalidStateException("Particle missing required attribues"\ + " in cast")); return D(p); } Index: kernel/include/IMP/decorators/macros.h =================================================================== --- kernel/include/IMP/decorators/macros.h (revision 388) +++ kernel/include/IMP/decorators/macros.h (working copy) @@ -195,7 +195,8 @@ Type internal_get_##name(unsigned int i) const{ \ IMP_DECORATOR_GET(get_##name##_key(i), Type, \ return VALUE, \ - throw IndexException(); return Type()); \ + throw IndexException("Particle missing attribute");\ + return Type()); \ } \ int internal_add_##name(Type t); \ unsigned int internal_get_number_of_##name() const { \ Index: kernel/include/IMP/decorators/MolecularHierarchyDecorator.h =================================================================== --- kernel/include/IMP/decorators/MolecularHierarchyDecorator.h (revision 388) +++ kernel/include/IMP/decorators/MolecularHierarchyDecorator.h (working copy) @@ -93,11 +93,12 @@ unsigned int add_child(This o) { IMP_check(get_type() > o.get_type(), "Parent type must subsume child type", - InvalidStateException()); + InvalidStateException("Type of hierarchy parent must be "\ + "higher than type of child")); IMP_check(get_type() != UNKNOWN, "Parent must have known type", - InvalidStateException()); + InvalidStateException("Hierarchy parent must have known type")); IMP_check(o.get_type() != UNKNOWN, "Child must have known type", - InvalidStateException()); + InvalidStateException("Hierarchy child must have known type")); return P::add_child(o); } Index: kernel/include/IMP/exception.h =================================================================== --- kernel/include/IMP/exception.h (revision 0) +++ kernel/include/IMP/exception.h (revision 0) @@ -0,0 +1,136 @@ +/** + * \file exception.h \brief Exception definitions and assertions. + * + * Copyright 2007-8 Sali Lab. All rights reserved. + * + */ +#ifndef __IMP_EXCEPTIONS_H +#define __IMP_EXCEPTIONS_H + +#include +#include + +namespace IMP +{ +//! The general base class for IMP exceptions +/** This way we can catch IMP exceptions without getting memory allocation + errors and everything. And it enforces having a description. + */ +class IMPDLLEXPORT Exception { + std::string message_; +public: + const char *what() const throw() { + return message_.c_str(); + } + Exception(const std::string &message) : message_(message){} + Exception(const char *message): message_(message){} + ~Exception() throw() {} +}; + +//! A general exception for an error in IMP. +/** \ingroup assert + */ +struct IMPDLLEXPORT ErrorException: public Exception +{ + ErrorException(): Exception("Fatal error"){} +}; + +//! An exception for an invalid model state +/** \ingroup assert + */ +class IMPDLLEXPORT InvalidStateException : public Exception +{ +public: + InvalidStateException(std::string t): Exception(t){} + InvalidStateException(const char *t): Exception(t){} +}; +// +//! An exception for trying to access an inactive particle +/** \ingroup assert + */ +class IMPDLLEXPORT InactiveParticleException : public Exception +{ +public: + InactiveParticleException(): + Exception("Attempting to use inactive particle"){} +}; + +//! An exception for a request for an invalid member of a container +/** \ingroup assert + */ +class IMPDLLEXPORT IndexException: public Exception +{ +public: + IndexException(std::string t): Exception(t){} + IndexException(const char *t): Exception(t){} +}; + +//! An exception for a passing an out of range value +/** \ingroup assert + */ +class IMPDLLEXPORT ValueException: public Exception +{ +public: + ValueException(std::string t): Exception(t){} + ValueException(const char *t): Exception(t){} +}; + + +namespace internal { + //! This is just here so you can catch errors more easily in the debugger + /** + Break on Log.cpp:19 to catch assertion failures. + \ingroup assert + */ + IMPDLLEXPORT void assert_fail(); + + //! Here so you can catch check failures more easily in the debugger + /** + Break on Log.cpp:22 to catch check failures. + \ingroup assert + */ + IMPDLLEXPORT void check_fail(); +} + +} + + +#ifndef NDEBUG + +//! An assertion for IMP. An IMP::ErrorException will be thrown. +/** Since it is a debug-only check and no attempt should be made to + recover from it, the exception type cannot be specified. + + \param[in] expr The assertion expression. + \param[in] message Write this message if the assertion fails. + \ingroup assert + */ +#define IMP_assert(expr, message) \ + if (!(expr)) { \ + IMP_ERROR(message); \ + IMP::internal::assert_fail(); \ + } +#else +#define IMP_assert(expr, message) +#endif + +//! A runtime check for IMP. +/** \param[in] expr The assertion expression. + \param[in] message Write this message if the assertion fails. + \param[in] exception Throw the object constructed by this expression. + \ingroup assert + */ +#define IMP_check(expr, message, exception) \ + if (!(expr)) { \ + IMP_ERROR(message); \ + throw exception; \ + } + +//! A runtime failure for IMP. +/** \param[in] message Write this message if the assertion fails. + \param[in] exception Throw the object constructed by this expression. + \ingroup assert + */ +#define IMP_failure(message, exception) {IMP_ERROR(message); throw exception;} + +#endif Index: kernel/include/IMP/SConscript =================================================================== --- kernel/include/IMP/SConscript (revision 388) +++ kernel/include/IMP/SConscript (working copy) @@ -7,7 +7,7 @@ 'Key.h', 'utility.h', 'Restraint.h', 'Optimizer.h', 'DecoratorBase.h', 'Object.h', 'Vector3D.h', 'ScoreFuncParams.h', 'UnaryFunction.h', 'PairScore.h', 'SingletonScore.h', 'macros.h', - 'TripletScore.h'] + 'TripletScore.h', 'exception.h'] # Install the include files: includedir = os.path.join(env['includedir'], 'IMP') Index: kernel/include/IMP/log.h =================================================================== --- kernel/include/IMP/log.h (revision 388) +++ kernel/include/IMP/log.h (working copy) @@ -8,14 +8,15 @@ #ifndef __IMP_LOG_H #define __IMP_LOG_H +#include "IMP_config.h" +#include "exception.h" + #include #include #include #include #include -#include "IMP_config.h" - namespace IMP { @@ -91,49 +92,7 @@ static Log *logpt_; }; -//! A general exception for an error in IMP. -/** \ingroup assert - */ -class IMPDLLEXPORT ErrorException: public std::exception -{ -}; -//! An exception for an invalid model state -/** \ingroup assert - */ -class IMPDLLEXPORT InvalidStateException : public std::exception -{ -public: - //! just eat the string for now - template - InvalidStateException(T){} - InvalidStateException(){} -}; -// -//! An exception for trying to access an inactive particle -/** \ingroup assert - */ -class IMPDLLEXPORT InactiveParticleException : public std::exception -{ -public: - //! just eat the string for now - template - InactiveParticleException(T){} - InactiveParticleException(){} -}; - -//! An exception for a request for an invalid member of a container -/** \ingroup assert - */ -class IMPDLLEXPORT IndexException: public std::exception -{ -public: - //! just eat the string for now - template - IndexException(T){} - IndexException(){} -}; - //! Set the current log level for IMP /** \ingroup log */ @@ -218,21 +177,7 @@ LogTarget target_; }; -namespace internal { - //! This is just here so you can catch errors more easily in the debugger - /** - Break on Log.cpp:19 to catch assertion failures. - \ingroup assert - */ - IMPDLLEXPORT void assert_fail(); - //! Here so you can catch check failures more easily in the debugger - /** - Break on Log.cpp:22 to catch check failures. - \ingroup assert - */ - IMPDLLEXPORT void check_fail(); -} } // namespace IMP @@ -305,44 +250,6 @@ #define IMP_LOG_WRITE(l,e) #endif -#ifndef NDEBUG -//! An assertion for IMP. An IMP::ErrorException will be thrown. -/** Since it is a debug-only check and no attempt should be made to - recover from it, the exception type cannot be specified. - \param[in] expr The assertion expression. - \param[in] message Write this message if the assertion fails. - \ingroup assert - */ -#define IMP_assert(expr, message) \ - if (!(expr)) { \ - IMP_ERROR(message); \ - IMP::internal::assert_fail(); \ - } -#else -#define IMP_assert(expr, message) -#endif - -//! A runtime check for IMP. -/** \param[in] expr The assertion expression. - \param[in] message Write this message if the assertion fails. - \param[in] exception Throw the object constructed by this expression. - \ingroup assert - */ -#define IMP_check(expr, message, exception) \ - if (!(expr)) { \ - IMP_ERROR(message); \ - throw exception; \ - } - -//! A runtime failure for IMP. -/** \param[in] message Write this message if the assertion fails. - \param[in] exception Throw the object constructed by this expression. - \ingroup assert - */ -#define IMP_failure(message, exception) {IMP_ERROR(message); throw exception;} - - - #endif /* __IMP_LOG_H */ Index: kernel/pyext/IMP_exceptions.i =================================================================== --- kernel/pyext/IMP_exceptions.i (revision 388) +++ kernel/pyext/IMP_exceptions.i (working copy) @@ -20,7 +20,9 @@ SWIG_exception(SWIG_ValueError, e.what()); } catch (IMP::ErrorException &e) { SWIG_exception(SWIG_RuntimeError, e.what()); - } + } catch (IMP::ValueException &e) { + SWIG_exception(SWIG_ValueError, e.what()); + } /* SWIG_exception contains "goto fail" so make sure the label is defined */ fail: return;