mxlib
c++ tools for analyzing astronomical data and other tasks by Jared R. Males. [git repo]
Loading...
Searching...
No Matches
exception_test.cpp
Go to the documentation of this file.
1/** \file exception_test.cpp
2 * \brief Tests mxlib exception construction, inspection, and nested-exception reporting.
3 */
4#include "../../catch2/catch.hpp"
5
7
8#include <sstream>
9#include <stdexcept>
10#include <string>
11#include <vector>
12
13/** \defgroup exception_unit_tests Exception Unit Tests
14 * \ingroup error_unit_tests
15 */
16
17namespace unitTest::error_exception_test
18{
19
20/** \brief Verifies all mx::exception constructors and accessors used by hciReduce error paths.
21 *
22 * \ingroup exception_unit_tests
23 */
24TEST_CASE( "exception preserves error context", "[error::exception]" )
25{
26 const int locationLine = __LINE__ + 1;
27 const mx::exception<mx::verbose::vv> locationOnly;
28
29 REQUIRE( locationOnly.code() == mx::error_t::exception );
30 REQUIRE( locationOnly.message().empty() );
31 REQUIRE( locationOnly.line() == locationLine );
32 REQUIRE( locationOnly.file_name().find( "exception_test.cpp" ) != std::string::npos );
33 REQUIRE( std::string( locationOnly.what() ).find( "exception" ) != std::string::npos );
34
35 const mx::exception<mx::verbose::vv> messageOnly( "custom explanation" );
36 REQUIRE( messageOnly.code() == mx::error_t::exception );
37 REQUIRE( messageOnly.message() == "custom explanation" );
38 REQUIRE( std::string( messageOnly.what() ).find( "custom explanation" ) != std::string::npos );
39
40 const mx::exception<mx::verbose::vv> codeAndMessage( mx::error_t::invalidarg, "invalid input" );
41 REQUIRE( codeAndMessage.code() == mx::error_t::invalidarg );
42 REQUIRE( codeAndMessage.message() == "invalid input" );
43 REQUIRE( std::string( codeAndMessage.what() ).find( "invalid input" ) != std::string::npos );
44
46 REQUIRE( codeOnly.code() == mx::error_t::sizeerr );
47 REQUIRE( codeOnly.message().empty() );
48 REQUIRE( std::string( codeOnly.what() ).find( "sizeerr" ) != std::string::npos );
49}
50
51/** \brief Verifies recursive extraction of standard and non-standard nested exceptions.
52 *
53 * \ingroup exception_unit_tests
54 */
55TEST_CASE( "unwind_exceptions extracts nested messages", "[error::exception]" )
56{
57 std::vector<std::string> messages;
58
59 try
60 {
61 try
62 {
63 throw std::runtime_error( "inner failure" );
64 }
65 catch( ... )
66 {
67 std::throw_with_nested( mx::exception<mx::verbose::vv>( mx::error_t::exception, "outer failure" ) );
68 }
69 }
70 catch( const std::exception &exception )
71 {
72 mx::unwind_exceptions( messages, exception );
73 }
74
75 REQUIRE( messages.size() == 2 );
76 REQUIRE( messages[0].find( "outer failure" ) != std::string::npos );
77 REQUIRE( messages[1] == "inner failure" );
78
79 messages.clear();
80 try
81 {
82 try
83 {
84 throw 17;
85 }
86 catch( ... )
87 {
88 std::throw_with_nested(
89 mx::exception<mx::verbose::vv>( mx::error_t::exception, "non-standard nested failure" ) );
90 }
91 }
92 catch( const std::exception &exception )
93 {
94 mx::unwind_exceptions( messages, exception );
95 }
96
97 REQUIRE( messages.size() == 1 );
98 REQUIRE( messages[0].find( "non-standard nested failure" ) != std::string::npos );
99}
100
101/** \brief Verifies the ladder format produced by mx::print_exceptions.
102 *
103 * \ingroup exception_unit_tests
104 */
105TEST_CASE( "print_exceptions formats nested messages", "[error::exception]" )
106{
107 std::vector<std::string> messages{ "outer failure", "inner failure" };
108 std::ostringstream captured;
109 std::streambuf *original = std::cerr.rdbuf( captured.rdbuf() );
110
111 mx::print_exceptions( messages, "processing failed" );
112
113 std::cerr.rdbuf( original );
114 REQUIRE( captured.str() == "processing failed:\n inner failure\n |-->outer failure\n" );
115}
116
117} // namespace unitTest::error_exception_test
Augments an exception with the source file and line.
Definition exception.hpp:42
const std::string & message() const
Get the message.
error_t code() const
Get the error code.
const std::string file_name() const
Get the source file.
int line() const
Get the source line.
virtual const char * what() const noexcept
Get the what string.
The mxlib exception class.
@ sizeerr
A size was invalid or calculated incorrectly.
Definition error_t.hpp:35
@ exception
An exception was thrown.
Definition error_t.hpp:51
@ invalidarg
An argument was invalid.
Definition error_t.hpp:29
TEST_CASE("exception preserves error context", "[error::exception]")
Verifies all mx::exception constructors and accessors used by hciReduce error paths.
void print_exceptions(std::vector< std::string > &whats, const std::string &message="exception(s) thrown")
Print nested exceptions to stderr, from the earliest to latest.
void unwind_exceptions(std::vector< std::string > &whats, const std::exception &e)
Extract the explanatory string of nested exceptions, placing them in a vector.