diff --git a/crates/ark/src/interface.rs b/crates/ark/src/interface.rs index 8eed05f21..ad70acd04 100644 --- a/crates/ark/src/interface.rs +++ b/crates/ark/src/interface.rs @@ -64,6 +64,7 @@ use harp::exec::r_peek_error_buffer; use harp::exec::r_sandbox; use harp::exec::RFunction; use harp::exec::RFunctionExt; +use harp::exec::RE_STACK_OVERFLOW; use harp::library::RLibraries; use harp::line_ending::convert_line_endings; use harp::line_ending::LineEnding; @@ -2225,9 +2226,6 @@ fn new_incomplete_reply(req: &ExecuteRequest, exec_count: u32) -> amalthea::Resu Err(amalthea::Error::ShellErrorExecuteReply(error, exec_count)) } -static RE_STACK_OVERFLOW: Lazy = - Lazy::new(|| Regex::new(r"C stack usage [ 0-9]+ is too close to the limit\n").unwrap()); - fn new_execute_reply(exec_count: u32) -> amalthea::Result { Ok(ExecuteReply { status: Status::Ok, diff --git a/crates/harp/src/exec.rs b/crates/harp/src/exec.rs index 0bc0e0b86..70ac17195 100644 --- a/crates/harp/src/exec.rs +++ b/crates/harp/src/exec.rs @@ -11,6 +11,8 @@ use std::os::raw::c_void; use anyhow::anyhow; use libr::*; +use once_cell::sync::Lazy; +use regex::Regex; use crate::call::RCall; use crate::environment::R_ENVS; @@ -22,6 +24,9 @@ use crate::object::RObject; use crate::r_symbol; use crate::utils::r_stringify; +pub static RE_STACK_OVERFLOW: Lazy = + Lazy::new(|| Regex::new(r"C stack usage [ 0-9]+ is too close to the limit\n").unwrap()); + pub struct RFunction { pub call: RCall, is_namespaced: bool, @@ -296,10 +301,13 @@ where /// and long jumps. /// /// If a longjump does occur for any reason (including but not limited to R -/// errors), the caller is notified, in this case by an `Err` return value -/// of kind `TopLevelExecError`. The error message contains the contents of -/// the C-level error buffer. It might or might not be related to the cause -/// of the longjump. The error also carries a Rust backtrace. +/// errors), the caller is notified, in this case by an `Err` return value of +/// kind `TopLevelExecError`. +/// +/// If the longjump occurs after a stack overflow error, this is indicated in +/// the error message. Note that it's possible the stackoverflow did not +/// actually cause that particular longjump, it's only indicative that it did +/// happen prior to the longjump. The error also carries a Rust backtrace. /// /// `top_level_exec()` is a low-level operator. Prefer using `try_catch()` /// if possible: @@ -351,7 +359,7 @@ where None => { let mut err_buf = r_peek_error_buffer(); - if err_buf.len() > 0 { + if RE_STACK_OVERFLOW.is_match(&err_buf) { err_buf = format!("\nLikely caused by:\n{err_buf}"); }