Improved dai::Exception object (it now stores more information and doesn't print...
authorJoris Mooij <joris.mooij@tuebingen.mpg.de>
Tue, 12 Jul 2011 13:09:22 +0000 (15:09 +0200)
committerJoris Mooij <joris.mooij@tuebingen.mpg.de>
Tue, 12 Jul 2011 13:09:22 +0000 (15:09 +0200)
Makefile
examples/example.cpp
include/dai/exceptions.h
src/daialg.cpp
src/matlab/dai.cpp
tests/testdai.cpp
tests/unit/exceptions_test.cpp
utils/fginfo.cpp

index dc78808..5ee5604 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -132,7 +132,7 @@ examples : $(EXAMPLES)
 matlabs : matlab/dai$(ME) matlab/dai_readfg$(ME) matlab/dai_writefg$(ME) matlab/dai_potstrength$(ME)
 
 unittests : tests/unit/var_test$(EE) tests/unit/smallset_test$(EE) tests/unit/varset_test$(EE) tests/unit/graph_test$(EE) tests/unit/dag_test$(EE) tests/unit/bipgraph_test$(EE) tests/unit/weightedgraph_test$(EE) tests/unit/enum_test$(EE) tests/unit/enum_test$(EE) tests/unit/util_test$(EE) tests/unit/exceptions_test$(EE) tests/unit/properties_test$(EE) tests/unit/index_test$(EE) tests/unit/prob_test$(EE) tests/unit/factor_test$(EE) tests/unit/factorgraph_test$(EE) tests/unit/clustergraph_test$(EE) tests/unit/regiongraph_test$(EE) tests/unit/daialg_test$(EE) tests/unit/alldai_test$(EE)
-       @echo 'Running unit tests...(note: output containing "EXCEPTION" does not indicate an error)'
+       @echo 'Running unit tests...'
        @echo
        tests/unit/var_test$(EE)
        tests/unit/smallset_test$(EE)
index cada3e5..b76c3aa 100644 (file)
@@ -53,7 +53,7 @@ int main( int argc, char *argv[] ) {
         try {
             boundTreewidth(fg, &eliminationCost_MinFill, maxstates );
         } catch( Exception &e ) {
-            if( e.code() == Exception::OUT_OF_MEMORY ) {
+            if( e.getCode() == Exception::OUT_OF_MEMORY ) {
                 do_jt = false;
                 cout << "Skipping junction tree (need more than " << maxstates << " states)." << endl;
             }
index 58d7380..2f4e7b0 100644 (file)
@@ -36,7 +36,7 @@
  *  DAI_THROW(NOT_IMPLEMENTED);
  *  \endcode
  */
-#define DAI_THROW(cod) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)))
+#define DAI_THROW(cod) throw dai::Exception(dai::Exception::cod, __FILE__, __PRETTY_FUNCTION__, DAI_TOSTRING(__LINE__), "")
 
 /// Macro that simplifies throwing an exception with a user-defined error message.
 /** \param cod Corresponds to one of the enum values of dai::Exception::Code
@@ -47,7 +47,7 @@
  *  DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message");
  *  \endcode
  */
-#define DAI_THROWE(cod,msg) throw dai::Exception(dai::Exception::cod, std::string(__FILE__ ", line " DAI_TOSTRING(__LINE__)), msg)
+#define DAI_THROWE(cod,msg) throw dai::Exception(dai::Exception::cod, __FILE__, __PRETTY_FUNCTION__, DAI_TOSTRING(__LINE__), msg)
 
 /// Assertion mechanism, similar to the standard assert() macro. It is always active, even if NDEBUG is defined
 #define DAI_ASSERT(condition) ((condition) ? ((void)0) : DAI_THROWE(ASSERTION_FAILED, std::string("Assertion \"" #condition "\" failed")))
@@ -99,21 +99,54 @@ class Exception : public std::runtime_error {
                    NUM_ERRORS};  // NUM_ERRORS should be the last entry
 
         /// Constructor
-        Exception( Code _code, const std::string& msg="", const std::string& detailedMsg="" ) : std::runtime_error(ErrorStrings[_code] + " [" +  msg + "]"), errorcode(_code) {
-            if( !detailedMsg.empty() )
-                std::cerr << "EXCEPTION: " << detailedMsg << std::endl;
-        }
+        Exception( Code code, const char *filename, const char *function, const char *line, const std::string& detailedMsg ) :
+            std::runtime_error(ErrorStrings[code] + (detailedMsg.empty() ? "" : (": " + detailedMsg)) + " [File " + filename + ", line " + line + ", function: " + function + "]"), 
+            _errorcode(code), _detailedMsg(detailedMsg), _filename(filename), _function(function), _line(line) {}
+
+        /// Destructor
+        ~Exception() throw () {}
+
+        /// Returns error code of this exception
+        Code getCode() const { return _errorcode; }
 
         /// Returns error code of this exception
-        Code code() const { return errorcode; }
+        /** \deprecated Please use dai::Exceptions::getCode() instead
+         */
+        Code code() const { return getCode(); }
+
+        /// Returns short error message of this exception
+        const std::string& getMsg() const { return ErrorStrings[_errorcode]; }
+
+        /// Returns detailed error message of this exception
+        const std::string& getDetailedMsg() const { return _detailedMsg; }
+
+        /// Returns filename where this exception was thrown
+        const std::string& getFilename() const { return _filename; }
+
+        /// Returns function name in which this exception was thrown
+        const std::string& getFunction() const { return _function; }
+
+        /// Returns line number where this exception was thrown
+        const std::string& getLine() const { return _line; }
 
         /// Returns error message corresponding to an error code
         const std::string& message( const Code c ) const { return ErrorStrings[c]; }
 
-
     private:
         /// Contains the error code of this exception
-        Code errorcode;
+        Code _errorcode;
+
+        /// Contains the detailed message of this exception, if any
+        std::string _detailedMsg;
+        
+        /// Contains the filename where this exception was thrown
+        std::string _filename;
+
+        /// Contains the function name in which this exception was thrown
+        std::string _function;
+
+        /// Contains the line number where this exception was thrown
+        std::string _line;
 
         /// Error messages corresponding to the exceptions enumerated above
         static std::string ErrorStrings[NUM_ERRORS];
index 5c80edf..99533e7 100644 (file)
@@ -48,7 +48,7 @@ Factor calcMarginal( const InfAlg &obj, const VarSet &vs, bool reInit ) {
             clamped->run();
             logZ = clamped->logZ();
         } catch( Exception &e ) {
-            if( e.code() == Exception::NOT_NORMALIZABLE )
+            if( e.getCode() == Exception::NOT_NORMALIZABLE )
                 logZ = -INFINITY;
             else
                 throw;
@@ -112,7 +112,7 @@ vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& vs, bool reIni
                             clamped->run();
                             logZ = clamped->logZ();
                         } catch( Exception &e ) {
-                            if( e.code() == Exception::NOT_NORMALIZABLE )
+                            if( e.getCode() == Exception::NOT_NORMALIZABLE )
                                 logZ = -INFINITY;
                             else
                                 throw;
@@ -167,7 +167,7 @@ vector<Factor> calcPairBeliefs( const InfAlg & obj, const VarSet& vs, bool reIni
                     clamped->run();
                     logZ = clamped->logZ();
                 } catch( Exception &e ) {
-                    if( e.code() == Exception::NOT_NORMALIZABLE )
+                    if( e.getCode() == Exception::NOT_NORMALIZABLE )
                         logZ = -INFINITY;
                     else
                         throw;
index b76f7d8..c33188c 100644 (file)
@@ -125,7 +125,7 @@ void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray*prhs[] ) {
         try {
             map_state = obj->findMaximum();
         } catch( Exception &e ) {
-            if( e.code() == Exception::NOT_IMPLEMENTED )
+            if( e.getCode() == Exception::NOT_IMPLEMENTED )
                 supported = false;
             else
                 throw;
index b96f7c6..b40efe0 100644 (file)
@@ -121,7 +121,7 @@ class TestDAI {
                     logZ = obj->logZ();
                     has_logZ = true;
                 } catch( Exception &e ) {
-                    if( e.code() == Exception::NOT_IMPLEMENTED )
+                    if( e.getCode() == Exception::NOT_IMPLEMENTED )
                         has_logZ = false;
                     else
                         throw;
@@ -132,7 +132,7 @@ class TestDAI {
                     maxdiff = obj->maxDiff();
                     has_maxdiff = true;
                 } catch( Exception &e ) {
-                    if( e.code() == Exception::NOT_IMPLEMENTED )
+                    if( e.getCode() == Exception::NOT_IMPLEMENTED )
                         has_maxdiff = false;
                     else
                         throw;
@@ -143,7 +143,7 @@ class TestDAI {
                     iters = obj->Iterations();
                     has_iters = true;
                 } catch( Exception &e ) {
-                    if( e.code() == Exception::NOT_IMPLEMENTED )
+                    if( e.getCode() == Exception::NOT_IMPLEMENTED )
                         has_iters = false;
                     else
                         throw;
@@ -160,7 +160,7 @@ class TestDAI {
                     try {
                         facMarginals.push_back( obj->beliefF( I ) );
                     } catch( Exception &e ) {
-                        if( e.code() == Exception::BELIEF_NOT_AVAILABLE )
+                        if( e.getCode() == Exception::BELIEF_NOT_AVAILABLE )
                             facMarginals.push_back( Factor( obj->fg().factor(I).vars(), INFINITY ) );
                         else
                             throw;
index 6f934d8..1503ed2 100644 (file)
@@ -30,26 +30,34 @@ BOOST_AUTO_TEST_CASE( ExceptionsTest ) {
     try {
         DAI_THROW(NOT_IMPLEMENTED);
     } catch( Exception& e ) {
-        BOOST_CHECK_EQUAL( e.code(), Exception::NOT_IMPLEMENTED );
-        BOOST_CHECK_EQUAL( e.message(e.code()), std::string("Feature not implemented") );
+        BOOST_CHECK_EQUAL( e.getCode(), Exception::NOT_IMPLEMENTED );
+        BOOST_CHECK_EQUAL( e.getMsg(), std::string("Feature not implemented") );
+        BOOST_CHECK_EQUAL( e.getDetailedMsg(), std::string("") );
+        BOOST_CHECK_EQUAL( e.getFilename(), std::string("tests/unit/exceptions_test.cpp") );
+        BOOST_CHECK_EQUAL( e.getFunction(), std::string("void ExceptionsTest::test_method()") );
+        BOOST_CHECK_EQUAL( e.getLine(), std::string("31") );
     }
 
     try {
         DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message");
     } catch( Exception& e ) {
-        BOOST_CHECK_EQUAL( e.code(), Exception::NOT_IMPLEMENTED );
-        BOOST_CHECK_EQUAL( e.message(e.code()), std::string("Feature not implemented") );
+        BOOST_CHECK_EQUAL( e.getCode(), Exception::NOT_IMPLEMENTED );
+        BOOST_CHECK_EQUAL( e.getMsg(), std::string("Feature not implemented") );
+        BOOST_CHECK_EQUAL( e.getDetailedMsg(), std::string("Detailed error message") );
+        BOOST_CHECK_EQUAL( e.getFilename(), std::string("tests/unit/exceptions_test.cpp") );
+        BOOST_CHECK_EQUAL( e.getFunction(), std::string("void ExceptionsTest::test_method()") );
+        BOOST_CHECK_EQUAL( e.getLine(), std::string("42") );
     }
 
     try {
         DAI_THROW(NOT_IMPLEMENTED);
     } catch( std::runtime_error& e ) {
-        BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented [tests/unit/exceptions_test.cpp, line 45]") );
+        BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented [File tests/unit/exceptions_test.cpp, line 53, function: void ExceptionsTest::test_method()]") );
     }
 
     try {
         DAI_THROWE(NOT_IMPLEMENTED,"Detailed error message");
     } catch( std::runtime_error& e ) {
-        BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented [tests/unit/exceptions_test.cpp, line 51]") );
+        BOOST_CHECK_EQUAL( e.what(), std::string("Feature not implemented: Detailed error message [File tests/unit/exceptions_test.cpp, line 59, function: void ExceptionsTest::test_method()]") );
     }
 }
index 3318179..024d229 100644 (file)
@@ -101,7 +101,7 @@ int main( int argc, char *argv[] ) {
             tw = boundTreewidth(fg, &eliminationCost_MinNeighbors, maxstates );
             cout << tw.first << " (" << tw.second << " states)" << endl;
         } catch( Exception &e ) {
-            if( e.code() == Exception::OUT_OF_MEMORY )
+            if( e.getCode() == Exception::OUT_OF_MEMORY )
                 cout << "> " << maxstates << endl;
             else
                 cout << "an exception occurred" << endl;
@@ -112,7 +112,7 @@ int main( int argc, char *argv[] ) {
             tw = boundTreewidth(fg, &eliminationCost_MinWeight, maxstates );
             cout << tw.first << " (" << tw.second << " states)" << endl;
         } catch( Exception &e ) {
-            if( e.code() == Exception::OUT_OF_MEMORY )
+            if( e.getCode() == Exception::OUT_OF_MEMORY )
                 cout << "> " << maxstates << endl;
             else
                 cout << "an exception occurred" << endl;
@@ -123,7 +123,7 @@ int main( int argc, char *argv[] ) {
             tw = boundTreewidth(fg, &eliminationCost_MinFill, maxstates );
             cout << tw.first << " (" << tw.second << " states)" << endl;
         } catch( Exception &e ) {
-            if( e.code() == Exception::OUT_OF_MEMORY )
+            if( e.getCode() == Exception::OUT_OF_MEMORY )
                 cout << "> " << maxstates << endl;
             else
                 cout << "an exception occurred" << endl;
@@ -134,7 +134,7 @@ int main( int argc, char *argv[] ) {
             tw = boundTreewidth(fg, &eliminationCost_WeightedMinFill, maxstates );
             cout << tw.first << " (" << tw.second << " states)" << endl;
         } catch( Exception &e ) {
-            if( e.code() == Exception::OUT_OF_MEMORY )
+            if( e.getCode() == Exception::OUT_OF_MEMORY )
                 cout << "> " << maxstates << endl;
             else
                 cout << "an exception occurred" << endl;