support NixErr::Recoverable

This commit is contained in:
do butterflies cry? 2026-04-10 10:14:05 +10:00
parent a81691c4be
commit d32c760213
Signed by: cry
GPG key ID: F68745A836CA0412
2 changed files with 27 additions and 2 deletions

View file

@ -118,6 +118,8 @@ impl Into<NixideResult<()>> for &ErrorContext {
.unwrap_or_else(|| panic_issue_call_failed!()), .unwrap_or_else(|| panic_issue_call_failed!()),
}, },
// XXX: WARNING: Recoverable only exists in later version of Nix
sys::NixErr::Recoverable => NixError::Recoverable,
sys::NixErr::Unknown => NixError::Unknown, sys::NixErr::Unknown => NixError::Unknown,
}; };

View file

@ -6,6 +6,22 @@ use crate::sys;
/// produced by the libnix C API. /// produced by the libnix C API.
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum NixError { pub enum NixError {
/// A recoverable error occurred.
///
/// # Reason
///
/// This is used primarily by C API *consumers* to communicate that a failed
/// primop call should be retried on the next evaluation attempt.
///
/// # Nix C++ API Internals
///
/// ```cpp
/// // `NIX_ERR_NIX_ERROR` variant of the `nix_err` enum type
/// NIX_ERR_RECOVERABLE = -4
/// ```
///
Recoverable,
/// A generic Nix error occurred. /// A generic Nix error occurred.
/// ///
/// # Reason /// # Reason
@ -19,6 +35,7 @@ pub enum NixError {
/// // `NIX_ERR_NIX_ERROR` variant of the `nix_err` enum type /// // `NIX_ERR_NIX_ERROR` variant of the `nix_err` enum type
/// NIX_ERR_NIX_ERROR = -4 /// NIX_ERR_NIX_ERROR = -4
/// ``` /// ```
///
ExprEval { name: String, info_msg: String }, ExprEval { name: String, info_msg: String },
/// A key/index access error occurred in C API functions. /// A key/index access error occurred in C API functions.
@ -47,6 +64,7 @@ pub enum NixError {
/// // `NIX_ERR_KEY` variant of the `nix_err` enum type /// // `NIX_ERR_KEY` variant of the `nix_err` enum type
/// NIX_ERR_KEY = -3 /// NIX_ERR_KEY = -3
/// ``` /// ```
///
KeyNotFound(Option<String>), KeyNotFound(Option<String>),
/// An overflow error occurred. /// An overflow error occurred.
@ -62,6 +80,7 @@ pub enum NixError {
/// // `NIX_ERR_OVERFLOW` variant of the `nix_err` enum type /// // `NIX_ERR_OVERFLOW` variant of the `nix_err` enum type
/// NIX_ERR_OVERFLOW = -2 /// NIX_ERR_OVERFLOW = -2
/// ``` /// ```
///
Overflow, Overflow,
/// An unknown error occurred. /// An unknown error occurred.
@ -77,6 +96,7 @@ pub enum NixError {
/// // `NIX_ERR_OVERFLOW` variant of the `nix_err` enum type /// // `NIX_ERR_OVERFLOW` variant of the `nix_err` enum type
/// NIX_ERR_UNKNOWN = -1 /// NIX_ERR_UNKNOWN = -1
/// ``` /// ```
///
Unknown, Unknown,
/// ///
@ -95,12 +115,14 @@ pub enum NixError {
/// This is solely a language difference between C++ and Rust, since /// This is solely a language difference between C++ and Rust, since
/// [sys::NixErr] is defined over the *"continuous" (not realy)* /// [sys::NixErr] is defined over the *"continuous" (not realy)*
/// type [::core::ffi::c_int]. /// type [::core::ffi::c_int].
///
Undocumented(sys::NixErr), Undocumented(sys::NixErr),
} }
impl Display for NixError { impl Display for NixError {
fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult { fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
match self { match self {
NixError::Recoverable => write!(f, "[libnix] Recoverable error occurred"),
NixError::ExprEval { name, info_msg } => write!( NixError::ExprEval { name, info_msg } => write!(
f, f,
"[libnix] NixExpr evaluation failed [name=\"{name}\", info_msg=\"{info_msg}\"]" "[libnix] NixExpr evaluation failed [name=\"{name}\", info_msg=\"{info_msg}\"]"
@ -120,12 +142,13 @@ impl Display for NixError {
impl NixError { impl NixError {
pub fn err_code(&self) -> sys::NixErr { pub fn err_code(&self) -> sys::NixErr {
match self { match self {
NixError::Overflow => sys::NixErr::Overflow, NixError::Recoverable => sys::NixErr::Recoverable,
NixError::KeyNotFound(_) => sys::NixErr::Key,
NixError::ExprEval { NixError::ExprEval {
name: _, name: _,
info_msg: _, info_msg: _,
} => sys::NixErr::NixError, } => sys::NixErr::NixError,
NixError::KeyNotFound(_) => sys::NixErr::Key,
NixError::Overflow => sys::NixErr::Overflow,
NixError::Unknown => sys::NixErr::NixError, NixError::Unknown => sys::NixErr::NixError,
NixError::Undocumented(err) => err.clone(), NixError::Undocumented(err) => err.clone(),
} }