<div dir="ltr">Thanks, I think I understand the issue better now. Ultimately, it comes down to the fact that UnwindProtect doesn't really allow handling of R conditions in the "regular" way as e.g. tryCatch() does; instead, it gives us just enough to properly unwind the C++ stack when an R error occurs. If I can summarize:<div><br></div><div>1. Client packages can catch the Rcpp LongjumpException and handle it themselves if they need to, but it's not obvious how to do this correctly.</div><div>2. R error messages are printed by R when the error is emitted.</div><div>3. It's not clear to the LongJumpException handler what R error triggered the longjmp exception.</div><div><br></div><div>In particular, for (1), Rcpp is normally responsible for unprotecting its unwind token, and then continuing the unwind:</div><div><br></div><div><a href="https://github.com/RcppCore/Rcpp/blob/1c8a1946db56e4d8041593906eddcb0da8ba07a0/inst/include/Rcpp/exceptions.h#L148-L157" target="_blank">https://github.com/RcppCore/Rcpp/blob/1c8a1946db56e4d8041593906eddcb0da8ba07a0/inst/include/Rcpp/exceptions.h#L148-L157</a><br></div><div><br></div><div>If we want to make it safe for client packages to catch these exceptions, we'd need to provide a helper for cleaning up Rcpp's unwind state, or make that happen automatically. (Maybe the token's protection status could be managed as part of the exception's lifetime? Not sure.) However, the fact that the LongjumpException needs special handling implies that it probably shouldn't inherit from std::exception.</div><div><br></div><div>For (2), I don't see a clean way of handling this beyond setting the 'show.error.messages' option to false. Unfortunately, because UnwindProtect is not a "real" R condition handler, it gets processed only after the "regular" R error machinery runs (which includes printing the error before actually jumping).</div><div><br></div><div>I'm similarly not aware of any solution for (3).</div><div><br></div><div>In other words, my understanding is that if you're a client of Rcpp and you want to be able to catch and handle R errors at the C++ level, UnwindProtect() isn't the right tool -- you'll want a proper tryCatch() handler.</div><div><br></div><div>It does also imply (as had been shown) that switching to unwind-protect would be a behavior change in Rcpp, which may not be ideal.</div><div><br></div><div>Thanks,</div><div>Kevin</div><div><br></div><div><br></div></div><div dir="ltr"><div><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Feb 6, 2022 at 9:39 AM Jeroen Ooms <<a href="mailto:jeroenooms@gmail.com" target="_blank">jeroenooms@gmail.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On Sun, Feb 6, 2022 at 6:25 PM Kevin Ushey <<a href="mailto:kevinushey@gmail.com" target="_blank">kevinushey@gmail.com</a>> wrote:<br>
><br>
> If I tweak your example package code so that all exceptions are caught via a catch (...) {} block, I can see something like:<br>
><br>
> > uptest::uptest()<br>
> Error in (function () : Ouch from R<br>
> Caught some other exception.<br>
><br>
> The fact that we're still printing the R error message seems undesirable, but it looks like the exception can be caught -- just not via std::exception.<br>
<br>
Yes that is also what Iñaki and me alluded to above. But I think this<br>
way, what we are catching is not the R error itself (which seems lost<br>
after it was printed), but rather a token that tells the application<br>
we should let Rcpp unwind all the way back to the R console. Which is<br>
what happens if we don't catch it, then it makes sense. But if we _do_<br>
want to handle the situation in C++, this doesn't give us much to work<br>
with.<br>
</blockquote></div></div>