Skip to content

CXX-1110 add CHECK_THROWS_WITH_CODE #1300

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Dec 11, 2024
Merged

Conversation

eramongodb
Copy link
Contributor

@eramongodb eramongodb commented Dec 10, 2024

Resolves CXX-1110. Verified by this patch (containing the proposed changes in #1298).

Precursor changes to faciliate the improvement and addition of tests for bsoncxx and mongocxx error codes and error categories as part of CXX-834 and CXX-2745.

The two new macros (CHECK|REQUIRE)_THROWS_WITH_CODE mirror the existing Catch2 exception assertion macros (CHECK|REQUIRE)_THROWS_WITH. It is expected to be used as follows:

CHECK_THROWS_WITH_CODE(throwing-expr, error-code-enumerator);
CHECK_THROWS_WITH_CODE(throwing-expr, error-code);
CHECK_THROWS_WITH_CODE(throwing-expr, error-condition);

The exception type must be or derive from std::system_error which provides the error code (via .code()) to be compared against. Otherwise, the test assertion fails via an always-false *_THROWS_WITH(throw, std::system_error) to reuse Catch's exception type-match error messages.

The option to define and use a custom Catch matcher for use with *_THROWS_WITH was rejected due to not correctly supporting Catch test exception propagation and not fully supporting customization of the resulting error messages due to unavoidable internal exception handler routines being executed within Catch. It was also comparatively unwieldy to write due to having to construct the custom matcher as an argument (its omission would just lead to the same *_THROWS_WITH_CODE interface as proposed by this PR):

CHECK_THROWS_WITH(throwing-expr, Code(error-code));

Although Catch seems to support string-making a std::error_code (e.g. std::errc::invalid_argument -> generic:22), it doesn't seem to support std::error_condition, so a specialization is also added which uses the same format as error codes. This produces assertion messages like the following:

// path/to/file:line: PASSED:
//   CHECK( ex.code() == (std::errc::invalid_argument)) )
// with expansion:
//   generic:22 == 22
CHECK_THROWS_WITH_CODE(..., std::errc::invalid_argument);

// path/to/file:line: PASSED:
//   CHECK( ex.code() == (std::make_error_code(std::errc::invalid_argument)) )
// with expansion:
//   generic:22 == generic:22
CHECK_THROWS_WITH_CODE(..., std::make_error_code(std::errc::invalid_argument));

// path/to/file:line: PASSED:
//   CHECK( ex.code() == (std::make_error_condition(std::errc::invalid_argument)) )
// with expansion:
//   generic:22 == generic:22
CHECK_THROWS_WITH_CODE(..., std::make_error_condition(std::errc::invalid_argument));

and in the event of an unexpected exception whose type does not provide ex.code() -> std::error_code:

// file:line: FAILED:
//   CHECK_THROWS_AS( throw, std::system_error )
// due to unexpected exception with message:
//   foo
CHECK_THROWS_WITH_CODE(throw std::runtime_error("foo"), std::errc::invalid_argument);

@eramongodb eramongodb requested a review from kevinAlbs December 10, 2024 17:15
@eramongodb eramongodb self-assigned this Dec 10, 2024
Copy link
Collaborator

@kevinAlbs kevinAlbs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. LGTM

(void)ex; /* Avoid unused variable warnings. */ \
_assertion(ex.code() == (_code)); \
} catch (...) { \
BSONCXX_CONCAT(_assertion, _THROWS_AS)(throw, std::system_error); \
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
BSONCXX_CONCAT(_assertion, _THROWS_AS)(throw, std::system_error); \
/* Unexpected. Use Catch _THROWS_AS to produce test failure */ \
BSONCXX_CONCAT(_assertion, _THROWS_AS)(throw, std::system_error); \

Suggest clarifying the assert is always expected to fail.

@eramongodb eramongodb merged commit db2bdfe into mongodb:master Dec 11, 2024
1 check was pending
@eramongodb eramongodb deleted the cxx-1110 branch December 11, 2024 22:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants