Macros for exception handling
1. Exception classes
All exceptions that can be raised by MRPT API are derived from the C++ standard std::exception
, so if you want to catch all of them, your code should have (at least at the top level, for example, in main()
) the following try/catch block:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
int main(int argc, char **argv) { try { // do whatever... return 0; } catch(std::exception &e) { std::cerr << e.what() << std::endl; return 1; } } |
In fact, all MRPT exceptions are of the types (derived from std::exception):
So if you want to handle in a different way one specific type of error, the following can be done:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
int main(int argc, char **argv) { try { // do whatever... return 0; } catch(mrpt::utils::CExceptionEOF &e) { // This was a EOF error std::cerr << e.what() << std::endl; return 1; } catch(std::exception &e) { // All other errors std::cerr << e.what() << std::endl; return 1; } } |
2. Exception raising macros (assert
-like MACROS)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
// A compile-time assertion MRPT_COMPILE_TIME_ASSERT( condition ) // A softer alternative to C assert() that doesn't // abort the program, but raises an std::exception ASSERT_( condition ) // As ASSERT_() but the exception will contain the given custom message // instead of a textual representation of "condition" ASSERTMSG_( condition, "custom message" ) // As ASSERT_(), but on fail displays a message like: // ASSERT_EQUAL(w.size(),v.size()) failed with // w.size()=10 // v.size()=12 ASSERT_EQUAL_( a, b ) ASSERT_NOT_EQUAL_( a, b ) ASSERT_BELOW_( a, b ) ASSERT_ABOVE_( a, b ) // As ASSERT_() but only has effect in DEBUG builds. ASSERTDEB_( condition ) // As ASSERTMSG_() but only has effect in DEBUG builds. ASSERTDEBMSG_( condition, "custom message" ) // Raises a std::logic_error exception with the custom message // and the source code file name, line number, and function name THROW_EXCEPTION("message") // Just like THROW_EXCEPTION() but the message has one printf-like format // specifier which is expanded with the second argument THROW_EXCEPTION_CUSTOM_MSG1("message %i", myVar ) // Checks for the existence of a file, raising an exception with an // explanatory message otherwise ASSERT_FILE_EXISTS_(fileName) |
Note that there’s no need to add a semicolon (;) at the end of the macros above.
3. Special MACROS for exception propagation
Most MRPT functions and methods use MRPT_START/MRPT_END macros, which enables (among other things) to automatically display the inverse call stack upon an exception. The exception e.what()
string will typically contain a stack trace like:
1 2 3 4 5 6 7 8 |
=============== MRPT EXCEPTION ============= size_t mrpt::math::KDTreeCapable::kdTreeClosestPoint2D(float, float, float&, float&, float&) const, line 201: Assert condition failed: x0==10 virtual void mrpt::slam::CPointsMap::computeMatchingWith2D(const mrpt::slam::CMetricMap*, const mrpt::poses::CPose2D&, float, float, const mrpt::poses::CPose2D&, mrpt::utils::TMatchingPairList&, float&, float*, bool, bool) const, line 586: mrpt::poses::CPosePDFPtr mrpt::slam::CICP::ICP_Method_Classic(const mrpt::slam::CMetricMap*, const mrpt::slam::CMetricMap*, const mrpt::poses::CPosePDFGaussian&, mrpt::slam::CICP::TReturnInfo&), line 562: virtual mrpt::poses::CPosePDFPtr mrpt::slam::CICP::AlignPDF(const mrpt::slam::CMetricMap*, const mrpt::slam::CMetricMap*, const mrpt::poses::CPosePDFGaussian&, float*, void*), line 104: void mrpt::slam::CMetricMapBuilderICP::processObservation(const mrpt::slam::CObservationPtr&), line 376: void MapBuilding_ICP(const std::string&), line 442: |