pub struct REvalError {
message: String,
classes: Vec<String>,
roots: Preserved,
}Expand description
An R error caught by RCall::eval / RCall::eval_base, r_eval_str,
the helpers built on them (REnv::package_namespace,
RCall::namespaced, dollar_extract), and try_eval_with_handlers /
RCall::try_eval_with_handlers.
It holds R’s condition object, rooted while this value lives, and what R reports about it:
message:conditionMessage(cond), the text R prints afterError in <call> :, without that prefix and without theCalls:traceback line of a non-interactive session;call:conditionCall(cond),Nonewhen it isNULL;classes: the class vector, most specific first;condition: the condition object itself.
Display writes the message alone. Every value holds a condition: a parse
failure in r_eval_str and an evaluation under RCall::eval that
jumps to the top level without an error (an interrupt) come back as a
simpleError built for them, with no call.
§Raising your own condition with it
The condition macros take the message through Display, and
reraise_class puts the package’s own classes
ahead of the caught ones:
use miniextendr_api::rust_error;
match RCall::new("print").arg(x).named_arg("na.print", na).eval_base() {
Ok(_) => {}
// The package's own class with R's message:
// class = "pkg_print_error"
// or with the caught classes kept after it, so a handler for those
// still matches:
Err(e) => rust_error!(class = e.reraise_class("pkg_print_error"), "{e}"),
}reraise raises the caught condition itself instead, as
R raised it.
A #[miniextendr] function returning Result<T, REvalError> raises the
caught message with the caught specific classes
(REvalError implements RConditionData).
For a Result<T, condition::RError> return, RError::from(e) takes the
message (it is a std::error::Error) and .class(...) adds the classes.
§Threads
!Send + !Sync: dropping the value releases its root on R’s precious list,
which is R main-thread state, and condition /
call hand out SEXPs. To carry the failure to another thread
or into a Send error type (anyhow::Error, Box<dyn Error + Send>),
take message or convert into
condition::RError.
Fields§
§message: StringconditionMessage(cond).
classes: Vec<String>class(cond).
roots: Preservedlist(cond, call), on R’s precious list while this value lives, where
call is conditionCall(cond) or NULL (see REvalError::call).
Its handle makes the value !Send + !Sync, see the type docs.
Implementations§
Source§impl REvalError
impl REvalError
Sourcepub fn message(&self) -> &str
pub fn message(&self) -> &str
The condition’s message (conditionMessage(cond)), without R’s
Error in <call> : prefix and Calls: line.
Sourcepub fn call(&self) -> Option<SEXP>
pub fn call(&self) -> Option<SEXP>
The condition’s call (conditionCall(cond)), None when it is NULL.
Also None for an error raised at the top of the evaluated expression
(stop() called directly rather than from a function): R gives such
an error the call of the tryCatch() frame the evaluation runs in,
doTryCatch(return(expr), name, parentenv, handler), which is no call
of the evaluated code. The condition object keeps
what R recorded.
The SEXP is rooted while this value lives; protect it to keep it longer.
Sourcepub fn classes(&self) -> &[String]
pub fn classes(&self) -> &[String]
The condition’s class vector, most specific first: for stop("boom"),
["simpleError", "error", "condition"].
Sourcepub fn inherits(&self, class: &str) -> bool
pub fn inherits(&self, class: &str) -> bool
Whether the condition’s class vector contains class.
Sourcepub fn specific_classes(&self) -> &[String]
pub fn specific_classes(&self) -> &[String]
The classes ahead of the base layers: the class vector without its
trailing rust_error, simpleError, error and condition, which the
condition macros add again. Empty for stop("boom"); ["my_class"]
for stop(errorCondition("boom", class = "my_class")) or for a
miniextendr function’s error!(class = "my_class", "boom").
Sourcepub fn reraise_class(&self, own: impl ConditionClass) -> Vec<String>
pub fn reraise_class(&self, own: impl ConditionClass) -> Vec<String>
The class vector for raising this error again as the package’s own
condition: own first (one class or several, most specific first),
then the caught specific classes not already
in own.
// stop(errorCondition("boom", class = "vctrs_error")) caught as `e`:
rust_error!(class = e.reraise_class(["pkg_print_error", "pkg_error"]), "{e}");
// class: pkg_print_error, pkg_error, vctrs_error, rust_error,
// simpleError, error, conditionSourcepub fn condition(&self) -> SEXP
pub fn condition(&self) -> SEXP
The condition object.
The SEXP is rooted while this value lives; protect it to keep it longer.
Sourcepub unsafe fn reraise(self) -> !
pub unsafe fn reraise(self) -> !
Raise the caught condition again, as R raised it: its classes, message
and fields are unchanged, and its call is call. So an
error raised at the top of the evaluated expression reports no call,
not R’s doTryCatch(...) frame.
Use it for the errors a body doesn’t explain itself, next to a
package’s own condition for the ones it does
(Quoted::try_eval_in has an example).
Unlike rust_error!(class = e.reraise_class(..), "{e}"), the condition
gets no rust_error class and keeps R’s call, not the wrapper’s.
The condition is signalled by base stop(cond), evaluated as
eval_with_handlers evaluates: the caller’s handlers see it, and the
exit stops at that evaluation’s R_UnwindProtect frame and leaves as a
Rust unwind. The frames up to the #[miniextendr] boundary drop their
values, and the boundary hands the exit back to R, which goes on to the
caller’s handler or to the top level. The same rules hold as for
eval_with_handlers: don’t catch the unwind with
std::panic::catch_unwind, and don’t call this from a Drop
implementation.
§Safety
As eval_with_handlers: R’s main thread, inside a miniextendr
boundary (a #[miniextendr] function body, a
with_r_unwind_protect
closure, …).
Sourceunsafe fn from_condition(cond: SEXP) -> Self
unsafe fn from_condition(cond: SEXP) -> Self
Take a caught condition: read its classes, message and call, and root the condition with its call.
§Safety
R’s main thread; cond is rooted by the caller for the call.
Sourceunsafe fn simple_error(message: &str) -> Self
unsafe fn simple_error(message: &str) -> Self
A simpleError with message and no call, for a failure that raised
no R condition (a parse failure, a jump to the top level, a result
RCall::eval_as can’t read).
§Safety
R’s main thread.
Trait Implementations§
Source§impl Debug for REvalError
impl Debug for REvalError
Source§impl Display for REvalError
impl Display for REvalError
Source§impl Error for REvalError
impl Error for REvalError
1.30.0 · Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
Source§#[doc(hidden)]fn type_id(&self, _: Internal) -> TypeIdwhere
Self: 'static,
#[doc(hidden)]fn type_id(&self, _: Internal) -> TypeIdwhere
Self: 'static,
error_type_id)TypeId of self.1.0.0 · Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl RConditionData for REvalError
Returned as a #[miniextendr] function’s Err, the caught error is raised
again with its message and its specific classes,
ahead of the rust_error layers; the call is the function’s own.
impl RConditionData for REvalError
Returned as a #[miniextendr] function’s Err, the caught error is raised
again with its message and its specific classes,
ahead of the rust_error layers; the call is the function’s own.
Source§fn data(&self) -> Option<ConditionData>
fn data(&self) -> Option<ConditionData>
e$<name>).Source§fn call(&self) -> ConditionCall
fn call(&self) -> ConditionCall
ConditionCall::None makes
conditionCall() NULL, like R’s call. = FALSE, for a condition
about the data rather than the call; the default keeps the call the
transport captured. Honoured by defer_* and by Result returns;
an argument-conversion error always keeps the call (see
conversion_err_parts). #[condition(call = none)] on a derived
type or variant overrides this.Auto Trait Implementations§
impl !Send for REvalError
impl !Sync for REvalError
impl Freeze for REvalError
impl RefUnwindSafe for REvalError
impl Unpin for REvalError
impl UnsafeUnpin for REvalError
impl UnwindSafe for REvalError
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<E> ConversionArgMessageClassed for Ewhere
E: RConditionData,
impl<E> ConversionArgMessageClassed for Ewhere
E: RConditionData,
Source§impl<E> ConversionErrClassed for Ewhere
E: RConditionData,
impl<E> ConversionErrClassed for Ewhere
E: RConditionData,
fn __mx_conversion_parts(&self, _expected_known: bool) -> ErrParts
Source§impl<E> ErrPartsClassed for Ewhere
E: RConditionData,
impl<E> ErrPartsClassed for Ewhere
E: RConditionData,
fn __mx_classed_parts(&self) -> Option<ErrParts>
Source§impl<T> RDebug for Twhere
T: Debug,
impl<T> RDebug for Twhere
T: Debug,
Source§impl<T> RError for Twhere
T: Error,
impl<T> RError for Twhere
T: Error,
Source§fn error_message(&self) -> String
fn error_message(&self) -> String
Source§fn error_chain(&self) -> Vec<String>
fn error_chain(&self) -> Vec<String>
Source§fn error_chain_length(&self) -> i32
fn error_chain_length(&self) -> i32
Source§#[doc(hidden)]unsafe extern "C" fn __RError_error_message_shim(
data: *mut c_void,
argc: i32,
argv: *const SEXP,
) -> SEXP
#[doc(hidden)]unsafe extern "C" fn __RError_error_message_shim(
data: *mut c_void,
argc: i32,
argv: *const SEXP,
) -> SEXP
RError::error_message. Read moreSource§impl<T> SizeHint for Twhere
T: ?Sized,
impl<T> SizeHint for Twhere
T: ?Sized,
Source§default fn lower_bound(&self) -> usize
default fn lower_bound(&self) -> usize
core_io_internals)[u8; 12] could return any value between 0 and
12 inclusively as a correct implementation. Read moreSource§impl<T> SizedTypeProperties for T
impl<T> SizedTypeProperties for T
Source§#[doc(hidden)]const SIZE: usize = _
#[doc(hidden)]const SIZE: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGN: usize = _
#[doc(hidden)]const ALIGN: usize = _
sized_type_properties)Source§#[doc(hidden)]const ALIGNMENT: Alignment = _
#[doc(hidden)]const ALIGNMENT: Alignment = _
ptr_alignment_type)Source§#[doc(hidden)]const IS_ZST: bool = _
#[doc(hidden)]const IS_ZST: bool = _
sized_type_properties)Source§#[doc(hidden)]const LAYOUT: Layout = _
#[doc(hidden)]const LAYOUT: Layout = _
sized_type_properties)Source§#[doc(hidden)]const MAX_SLICE_LEN: usize = _
#[doc(hidden)]const MAX_SLICE_LEN: usize = _
sized_type_properties)[Self]. Read moreLayout§
Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.
Size: 56 bytes