Repository navigation
turn exceptions during module initialization into r errors - #1526
Open
kevinushey wants to merge 1 commit into
Open
kevinushey wants to merge 1 commit into
kevinushey wants to merge 1 commit into
Conversation
This was referenced Oct 29, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1525.
The boot function generated by
RCPP_MODULEis anextern "C"entry point called from R via.Call(), but had noBEGIN_RCPP/END_RCPP. Any C++ exception thrown by the module body, such as Rcpp's ownstd::range_error("no such class")from.derives<T>()with a misspelled parent, escaped into R andstd::terminate()aborted the session. It also skipped::setCurrentScope( 0 ), leaving the global module scope pointing at the half-initialized module. See #1525 for the reprex. This is the boot-function counterpart of #1495 / #1496.Changes (
inst/include/Rcpp/Module.h):RCPP_MODULE: the boot function body is wrapped inBEGIN_RCPP/END_RCPP, so exceptions become R errors like in every other.Callentry point.Rcpp::internal::ModuleScope, a small RAII guard that sets the current module scope and clears it in its destructor, so the scope is reset on the error path as well as on success.The change is confined to the macro, so it applies to a package once it is rebuilt; nothing in
Rcpp.sochanges. One caller-visible difference: code that calls the boot function directly from C++ instead of through.Call(), such as RInside'sLOAD_RCPP_MODULE, now gets an R error rather than a C++ exception when the module body throws. Previously a throwing module body was fatal whenever it was loaded from R, so this only matters for that direct-call path.Tests:
inst/tinytest/cpp/ModuleInitError.cpp: a module whose body throws (derives()with a parent that was never exposed).inst/tinytest/test_module.R:sourceCpp()of that file raises theno such classR error, and afterwards the current module scope is cleared (checked through a small exported helper added tocpp/Module.cpp).Verification:
SIGABRT, exit code 134) against current master and printsresult: no such classwith exit code 0 against this branch.test_module.R(47/47),test_modref.R,test_expose_class.Randtest_module_client_package.Rpass withRunAllRcppTests=yes RunVerboseRcppTests=yes(R 4.6.1, macOS).-Wall -Wextra -Wpedantic -Wconversion -Wshadow -Wunreachable-codereports no warnings from the new macro or guard.Checklist
R CMD checkstill passes all tests (module test files run locally as above)