File tree Expand file tree Collapse file tree 3 files changed +64
-3
lines changed Expand file tree Collapse file tree 3 files changed +64
-3
lines changed Original file line number Diff line number Diff line change @@ -1465,14 +1465,14 @@ impl RMain {
14651465 /// https://github.com/rstudio/renv/blob/5d0d52c395e569f7f24df4288d949cef95efca4e/inst/resources/activate.R#L85-L87
14661466 fn handle_invalid_input_request ( & self , buf : * mut c_uchar , buflen : c_int ) -> ConsoleResult {
14671467 if let Some ( input) = Self :: renv_autoloader_reply ( ) {
1468- log:: info !( "Detected `readline()` call in renv autoloader. Returning `'{input}'`." ) ;
1468+ log:: warn !( "Detected `readline()` call in renv autoloader. Returning `'{input}'`." ) ;
14691469 match Self :: on_console_input ( buf, buflen, input) {
14701470 Ok ( ( ) ) => return ConsoleResult :: NewInput ,
14711471 Err ( err) => return ConsoleResult :: Error ( format ! ( "{err}" ) ) ,
14721472 }
14731473 }
14741474
1475- log:: info !( "Detected invalid `input_request` outside an `execute_request`. Preparing to throw an R error." ) ;
1475+ log:: warn !( "Detected invalid `input_request` outside an `execute_request`. Preparing to throw an R error." ) ;
14761476
14771477 let message = vec ! [
14781478 "Can't request input from the user at this time." ,
Original file line number Diff line number Diff line change @@ -201,7 +201,33 @@ invoke_option_error_handler <- function() {
201201 }
202202
203203 for (hnd in handler ) {
204- eval(hnd , globalenv())
204+ err <- tryCatch(
205+ {
206+ eval(hnd , globalenv())
207+ NULL
208+ },
209+ error = identity
210+ )
211+
212+ if (! is.null(err )) {
213+ # Disable error handler to avoid cascading errors
214+ options(error = NULL )
215+
216+ # We don't let the error propagate to avoid a confusing sequence of
217+ # error messages from R, such as "Error during wrapup"
218+ writeLines(
219+ c(
220+ " The `getOption(\" error\" )` handler failed." ,
221+ " This option was unset to avoid cascading errors." ,
222+ " Caused by:" ,
223+ conditionMessage(err )
224+ ),
225+ con = stderr()
226+ )
227+
228+ # Bail early
229+ return ()
230+ }
205231 }
206232}
207233
Original file line number Diff line number Diff line change @@ -820,6 +820,41 @@ fn test_env_vars() {
820820 assert_eq ! ( frontend. recv_shell_execute_reply( ) , input. execution_count) ;
821821}
822822
823+ #[ test]
824+ fn test_execute_request_error_handler_failure ( ) {
825+ let frontend = DummyArkFrontend :: lock ( ) ;
826+
827+ // Define the functions and set the error handler
828+ let code = r#"
829+ f <- function() g()
830+ g <- function() h()
831+ h <- function() stop("foo")
832+ options(error = function() stop("ouch"))
833+ "# ;
834+ frontend. execute_request_invisibly ( code) ;
835+
836+ frontend. send_execute_request ( "f()" , ExecuteRequestOptions :: default ( ) ) ;
837+ frontend. recv_iopub_busy ( ) ;
838+ let input = frontend. recv_iopub_execute_input ( ) ;
839+ assert_eq ! ( input. code, "f()" ) ;
840+
841+ frontend. recv_iopub_stream_stderr (
842+ r#"The `getOption("error")` handler failed.
843+ This option was unset to avoid cascading errors.
844+ Caused by:
845+ ouch
846+ "# ,
847+ ) ;
848+
849+ assert ! ( frontend. recv_iopub_execute_error( ) . contains( "foo" ) ) ;
850+
851+ frontend. recv_iopub_idle ( ) ;
852+ assert_eq ! (
853+ frontend. recv_shell_execute_reply_exception( ) ,
854+ input. execution_count
855+ ) ;
856+ }
857+
823858/// Install a SIGINT handler for shutdown tests. This overrides the test runner
824859/// handler so it doesn't cancel our test.
825860fn install_sigint_handler ( ) {
You can’t perform that action at this time.
0 commit comments