Skip to main content

org_gdocs/
error.rs

1//! Typed error surface for the `org-gdocs` library.
2//!
3//! Every distinct failure a caller might branch on is its own variant. `anyhow`
4//! is confined to the binary edge and never appears here.
5
6use std::path::PathBuf;
7
8/// Errors raised by `org-gdocs` library code.
9#[derive(Debug, thiserror::Error)]
10pub enum Error {
11    /// A filesystem operation failed for the given path.
12    #[error("I/O error at {path}: {source}")]
13    Io {
14        /// Path the failing operation targeted.
15        path: PathBuf,
16        /// Underlying I/O error.
17        source: std::io::Error,
18    },
19
20    /// The configuration file could not be parsed as TOML.
21    #[error("invalid TOML configuration: {0}")]
22    ConfigToml(#[from] toml::de::Error),
23
24    /// The configuration could not be serialized to TOML.
25    #[error("could not serialize TOML configuration: {0}")]
26    ConfigTomlSerialize(#[from] toml::ser::Error),
27
28    /// A JSON value could not be (de)serialized.
29    ///
30    /// JSON is confined to the forced external boundaries (the Google API wire
31    /// format and OAuth credential/token files, OVR-1/A5); surfaces this crate
32    /// owns use s-expressions and surface [`Error::Sexp`] instead.
33    #[error("JSON error: {0}")]
34    Json(#[from] serde_json::Error),
35
36    /// An s-expression (the `** Sync State` block or the CLI↔Emacs envelope, A5)
37    /// could not be parsed or did not match the expected shape.
38    #[error("s-expression error: {0}")]
39    Sexp(#[from] crate::sexp::SexpError),
40
41    /// A Google Docs or Drive API call failed — transport, protocol, or a
42    /// non-success API response.
43    ///
44    /// The generated client's error type is mapped to its display string at the
45    /// single seam in [`crate::google::client`] (F6) so it never leaks into this
46    /// crate's public surface (EI-1).
47    #[error("Google API error: {0}")]
48    Google(String),
49
50    /// The target document exposes more than one tab, which is unsupported.
51    ///
52    /// We operate only on the first/legacy tab (DI-6); a multi-tab document is
53    /// reported rather than silently mis-indexed.
54    #[error("document has multiple tabs, which is unsupported (operate on a single-tab document)")]
55    MultipleTabs,
56
57    /// The org body could not be parsed by `tftio-kb`.
58    #[error("could not parse org body: {0}")]
59    OrgParse(String),
60
61    /// The org file has no linked Google Doc (`#+GDOC_ID:`).
62    ///
63    /// `pull`, `clean`, and `open` all require a document to have been created by
64    /// a prior `push`; this is the branchable failure they surface when it has not.
65    #[error("org file has no linked Google Doc (#+GDOC_ID:); run `push` first")]
66    NotLinked,
67
68    /// A required path could not be resolved (e.g. no home/config directory).
69    #[error("could not resolve {0}")]
70    PathResolution(String),
71
72    /// OAuth authentication, token acquisition, or TLS setup failed.
73    #[error("authentication error: {0}")]
74    Auth(String),
75}
76
77/// Convenience result alias for fallible `org-gdocs` library functions.
78pub type Result<T> = std::result::Result<T, Error>;