Skip to content

Commit 8441b97

Browse files
committed
Hook recover() to call browser()
The `recover()` functionality is provided by the call stack panes of frontends
1 parent 7a11d58 commit 8441b97

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

crates/ark/src/modules/positron/hooks.R

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,14 @@ register_hooks <- function() {
1414
new_ark_debug(base::debugonce),
1515
namespace = TRUE
1616
)
17+
18+
rebind(
19+
"utils",
20+
"recover",
21+
# Keep this wrapped up this way for a better "Called from:" call
22+
function(...) ark_recover(),
23+
namespace = TRUE
24+
)
1725
register_getHook_hook()
1826
}
1927

@@ -151,3 +159,11 @@ check_version <- function(pkg) {
151159
}
152160
)
153161
}
162+
163+
# We don't support `utils::recover()` in Ark, but the same functionality is
164+
# provided via the call stack pane of IDEs. So replace it by `browser()` so that
165+
# people can enter the debugger on error using the familiar `options(error =
166+
# recover)` gesture.
167+
ark_recover <- function(...) {
168+
browser()
169+
}

crates/ark/tests/kernel.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -892,6 +892,34 @@ Are you calling `readline()` or `menu()` from `options(error = )`?
892892
}
893893

894894
#[test]
895+
fn test_execute_request_error_recover() {
896+
let frontend = DummyArkFrontend::lock();
897+
898+
let code = r#"
899+
f <- function() g()
900+
g <- function() h()
901+
h <- function() stop("foo")
902+
options(error = recover)
903+
"#;
904+
frontend.execute_request_invisibly(code);
905+
906+
frontend.send_execute_request("f()", ExecuteRequestOptions::default());
907+
frontend.recv_iopub_busy();
908+
let input = frontend.recv_iopub_execute_input();
909+
assert_eq!(input.code, "f()");
910+
911+
// We set up the call stack to show a simple `error_handler()`
912+
frontend.recv_iopub_stream_stdout("Called from: ark_recover()\n");
913+
914+
assert!(frontend.recv_iopub_execute_error().contains("foo"));
915+
916+
frontend.recv_iopub_idle();
917+
assert_eq!(
918+
frontend.recv_shell_execute_reply_exception(),
919+
input.execution_count
920+
);
921+
}
922+
895923
/// Install a SIGINT handler for shutdown tests. This overrides the test runner
896924
/// handler so it doesn't cancel our test.
897925
fn install_sigint_handler() {

0 commit comments

Comments
 (0)