Comments (9)
And for completeness, note that you are still able to catch those errors in C++, but instead of std::exception
in your reprex above, you need to catch Rcpp::LongjumpException
. If you do this, please be sure to rethrow the exception, so that the unwind is completed. See #807 for a longer discussion.
library(Rcpp)
cppFunction(
'void evalStopFunction(const Rcpp::Function& fn) {
try {
fn();
} catch (const Rcpp::LongjumpException& e) {
std::rethrow_exception(std::current_exception());
} catch (...) {
throw std::runtime_error("Unknown Error");
}
}'
)
fn <- function() stop("Test")
evalStopFunction(fn)
#> Error in (function () : Test
from rcpp.
For reference, some of the related discussion:
Indeed, Rcpp no longer catches R errors and attempts to re-throw those as C++ exceptions, so code of the OP's form won't work as it did in previous builds of Rcpp. The consensus was that this was worth the breakage, since the amount of infrastructure around "safe" evaluation meant executing R code from Rcpp was very expensive.
from rcpp.
That ... strikes me as odd. I work with Rcpp all day and I surely do see errors caught and returned to R. Mind you the default and standard approach is to let Rcpp::stop()
throw an exception that will get caught, converted and returned.
And that still works:
> Rcpp::cppFunction(r"[void foo() { Rprintf("Hi\n"); Rcpp::stop("Bye"); Rprintf("Gone\n"); } ]")
> foo()
Hi
Error: Bye
>
Also are you aware that Rcpp injects try catch blocks for you? The above is not what compiles, try adding verbose=TRUE, rebuild=TRUE
to the end of your cppFunction()
call. The BEGIN_RCPP
and END_RCPP
get expanded.
Lastly, note the first item in the release notes. This may be what rattles you, and as noted you can turn it off.
Lines 36 to 43 in 3456999
Finally, if you use your standard C++ exception handling in functions not modified by Rcpp Attributes for you convenience it likely still works, We do not generally muck with exceptions because that would be ... crazy.
from rcpp.
It seems that the behavior changed with d389a8a.
from rcpp.
That is precisely the issue in NEWS that I pointed out to you, and it was preceeded by lengthy discussion. Unlikely to be reverted; I invite you to use the available toggle to turn it off if you do not want that behaviour. We try to give you a choice.
from rcpp.
Yup.
Code
#define RCPP_NO_UNWIND_PROTECT 1
#include <Rcpp/Rcpp>
// [[Rcpp::export]]
void evalStopFunction(const Rcpp::Function& fn) {
try {
fn();
} catch (const std::exception& e) {
std::rethrow_exception(std::current_exception());
} catch (...) {
throw std::runtime_error("Unknown Error");
}
}
/*** R
packageVersion("Rcpp")
fn <- function() stop("Test")
evalStopFunction(fn)
*/
Output
> Rcpp::sourceCpp("/tmp/issue1268.cpp")
> packageVersion("Rcpp")
[1] ‘1.0.10.5’
> fn <- function() stop("Test")
> evalStopFunction(fn)
Error in evalStopFunction(fn) : Evaluation error: Test.
>
All good?
from rcpp.
Sorry, I sent my last comment before seeing your answer. Thanks for your example; I see that disabling unwind protect reverts to the original behavior. I will also have a look if that is an option for my actual code. However, I still find the changed behavior odd, since I would have expected that function evaluation errors throw a Rcpp::eval_error
, deriving from std::exception
, that I can catch. For me, it looks like the evaluation stop("Test")
somehow bypasses the catch-block (see reprex below). If that is intended, please close the issue.
For a bit of background, the code I used for the reprex is a minimal working example of an actual use case, which is testing that exceptions generated by a C++ wrapper of R's C-API for numerical integration are thrown as intended. Rcpp is only used for convenience in testing the wrapper.
# RcppCore/[email protected]
library(Rcpp)
cppFunction(
'void evalStopFunction(const Rcpp::Function& fn) {
try {
fn();
} catch (...) {
// ignore
}
}'
)
fn <- function() stop("Test")
evalStopFunction(fn)
#> Error in (function () : Test
Created on 2023-06-29 with reprex v2.0.2
Session info
sessioninfo::session_info()
#> ─ Session info ───────────────────────────────────────────────────────────────
#> setting value
#> version R version 4.3.1 (2023-06-16)
#> os macOS Ventura 13.4
#> system aarch64, darwin20
#> ui X11
#> language (EN)
#> collate en_US.UTF-8
#> ctype en_US.UTF-8
#> tz Europe/Berlin
#> date 2023-06-29
#> pandoc 3.1.4 @ /opt/homebrew/bin/ (via rmarkdown)
#>
#> ─ Packages ───────────────────────────────────────────────────────────────────
#> package * version date (UTC) lib source
#> cli 3.6.1 2023-03-23 [1] CRAN (R 4.3.0)
#> digest 0.6.31 2022-12-11 [1] CRAN (R 4.3.0)
#> evaluate 0.21 2023-05-05 [1] CRAN (R 4.3.0)
#> fastmap 1.1.1 2023-02-24 [1] CRAN (R 4.3.0)
#> fs 1.6.2 2023-04-25 [1] CRAN (R 4.3.0)
#> glue 1.6.2 2022-02-24 [1] CRAN (R 4.3.0)
#> htmltools 0.5.5 2023-03-23 [1] CRAN (R 4.3.0)
#> knitr 1.43 2023-05-25 [1] CRAN (R 4.3.0)
#> lifecycle 1.0.3 2022-10-07 [1] CRAN (R 4.3.0)
#> magrittr 2.0.3 2022-03-30 [1] CRAN (R 4.3.0)
#> purrr 1.0.1 2023-01-10 [1] CRAN (R 4.3.0)
#> R.cache 0.16.0 2022-07-21 [1] CRAN (R 4.3.0)
#> R.methodsS3 1.8.2 2022-06-13 [1] CRAN (R 4.3.0)
#> R.oo 1.25.0 2022-06-12 [1] CRAN (R 4.3.0)
#> R.utils 2.12.2 2022-11-11 [1] CRAN (R 4.3.0)
#> Rcpp * 1.0.10 2023-01-22 [1] CRAN (R 4.3.0)
#> reprex 2.0.2 2022-08-17 [1] CRAN (R 4.3.0)
#> rlang 1.1.1 2023-04-28 [1] CRAN (R 4.3.0)
#> rmarkdown 2.22 2023-06-01 [1] CRAN (R 4.3.0)
#> rstudioapi 0.14 2022-08-22 [1] CRAN (R 4.3.0)
#> sessioninfo 1.2.2 2021-12-06 [1] CRAN (R 4.3.0)
#> styler 1.10.1 2023-06-05 [1] CRAN (R 4.3.0)
#> vctrs 0.6.3 2023-06-14 [1] CRAN (R 4.3.0)
#> withr 2.5.0 2022-03-03 [1] CRAN (R 4.3.0)
#> xfun 0.39 2023-04-20 [1] CRAN (R 4.3.0)
#> yaml 2.3.7 2023-01-23 [1] CRAN (R 4.3.0)
#>
#> [1] /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/library
#>
#> ──────────────────────────────────────────────────────────────────────────────
from rcpp.
If Rcpp's convenience gets in your way, you can disable it (I showed you how) and/or do not use the wrapper creation (see my first comment) and/or do your own try/catch handling and/or write basic SEXP foo(SEXP, ....)
and do.call()
that,
We generally do what we do for a reason, and this change was fairly long in coming and fairly important for both performance and edge cases (catching exceptions across compilation units can get hairy).
from rcpp.
Closing as documented and planned behavior exhibited here.
from rcpp.
Related Issues (20)
- Avoid readability-avoid-const-params-in-decls? HOT 5
- Add support for check.names HOT 5
- Compiler warning on windows-arm64 (libc++) HOT 3
- Figure 3 incorrect caption in Rcpp-introduction vignette HOT 2
- Upstreaming `std::tuple<>` support HOT 10
- sourceCpp crashes R when called about 1000 times on same code HOT 10
- Integer overflow in `MatrixRow` offset calculations for large matrices HOT 8
- Switch from S4SXP to OBJSXP HOT 2
- pass by const refererence HOT 1
- A fresh -Wformat-security issue under r-devel HOT 9
- 'CRAN package Rcpp' notice HOT 5
- Installation/Compiling Error for Package with Rcpp dependency - Ubuntu (rvmf.cpp?) HOT 5
- Exporting classes using `Rcpp::interfaces(cpp)` that are shared among multiple cpp files through header file HOT 13
- test_packageversion fails with Rcpp 1.0.12 HOT 3
- Question regarding replacement by reference of <RTYPE>Array class without making copy HOT 8
- Cannot make std::vector<int8_t> from NumericVector HOT 4
- issue building phangorn 2.11 for wasm HOT 3
- New warnings from -Wconversion -Wno-sign-conversion HOT 2
- compileAttributes and use of .External2() for calling native symbol routine HOT 6
- Exporting comments into function definitions HOT 3
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from rcpp.