From e5eef77d081e4edd24debfa2276bfe5eb02b9d44 Mon Sep 17 00:00:00 2001 From: Aleksa Sarai Date: Sat, 7 Dec 2024 20:28:05 +1100 Subject: [PATCH] errors: document and export ErrorKind ErrorKind is safe for us to export (unlike ErrorImpl) because we can easily change the concrete types we use for our errors without causing downstream breakages. Most users almost certainly would prefer something that looks like std::io::ErrorKind anyway (which matches how we check for libpathrs errors inside libpathrs as well). Signed-off-by: Aleksa Sarai --- CHANGELOG.md | 4 ++++ src/error.rs | 23 ++++++++++++++++++++--- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e121efe..c93e187d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). efficient in some scenarios (especially with the openat2-based resolver or for C FFI users where function calls are expensive) as it saves one file descriptor allocation and extra function calls. +- Error: `ErrorKind` is now exported, allowing you to programmatically handle + errors returned by libpathrs. This interface may change in the future (in + particular, `ErrorKind::OsError` might change its representation of `errno` + values). - capi: errors that are returned by libpathrs itself (such as invalid arguments being passed by users) will now contain a `saved_errno` value that makes sense for the error type (so `ErrorKind::InvalidArgument` will result in an diff --git a/src/error.rs b/src/error.rs index 8973b3e3..f4096a56 100644 --- a/src/error.rs +++ b/src/error.rs @@ -36,6 +36,10 @@ use std::{borrow::Cow, io::Error as IOError}; // export the crate types here without std::backtrace::Backtrace. // MSRV(1.65): Use std::backtrace::Backtrace. +/// Opaque error type for libpathrs. +/// +/// If you wish to do non-trivial error handling with libpathrs errors, use +/// [`Error::kind`] to get an [`ErrorKind`] you can handle programmatically. #[derive(thiserror::Error, Debug)] #[error(transparent)] pub struct Error(#[from] Box); @@ -49,7 +53,7 @@ impl> From for Error { } impl Error { - pub(crate) fn kind(&self) -> ErrorKind { + pub fn kind(&self) -> ErrorKind { self.0.kind() } } @@ -100,15 +104,28 @@ pub(crate) enum ErrorImpl { }, } -// TODO: Export this? +/// Underlying error class for libpathrs errors. +/// +/// This is similar in concept to [`std::io::ErrorKind`]. Note that the #[derive(Debug, PartialEq, Eq, Clone, Copy)] #[non_exhaustive] -pub(crate) enum ErrorKind { +pub enum ErrorKind { + /// The requested feature is not implemented in libpathrs. NotImplemented, + /// The requested feature is not supported by the system. NotSupported, + /// The provided arguments to libpathrs were invalid. InvalidArgument, + /// libpaths encountered a state where the safety of the operation could not + /// be guaranteeed. This is usually the result of an attack by a malicious + /// program. SafetyViolation, + /// Some internal error occurred. For more information, see the string + /// description of the original [`Error`]. InternalError, + /// The underlying error came from a system call. The provided + /// [`std::io::RawOsError`] is the numerical value of the `errno` number, if + /// available. // TODO: We might want to use Option? OsError(Option), }