Initial commit
This commit is contained in:
104
brittle-core/src/error.rs
Normal file
104
brittle-core/src/error.rs
Normal file
@@ -0,0 +1,104 @@
|
||||
use std::path::PathBuf;
|
||||
use thiserror::Error;
|
||||
|
||||
/// Top-level error returned from all public Brittle API methods.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BrittleError {
|
||||
#[error("{0}")]
|
||||
Store(#[from] StoreError),
|
||||
|
||||
#[error("{0}")]
|
||||
Validation(#[from] ValidationError),
|
||||
|
||||
#[error("{0}")]
|
||||
BibTeX(#[from] BibtexError),
|
||||
}
|
||||
|
||||
/// Errors from the storage layer.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum StoreError {
|
||||
#[error("{entity_type} not found: {id}")]
|
||||
NotFound { entity_type: EntityType, id: String },
|
||||
|
||||
#[error("I/O error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("serialization error: {message}")]
|
||||
Serialization { message: String },
|
||||
|
||||
#[error("deserialization error for {path}: {message}")]
|
||||
Deserialization { path: PathBuf, message: String },
|
||||
|
||||
#[error("git error: {0}")]
|
||||
Git(#[from] git2::Error),
|
||||
|
||||
#[error("repository not found at {path}")]
|
||||
RepoNotFound { path: PathBuf },
|
||||
|
||||
#[error("repository already exists at {path}")]
|
||||
RepoAlreadyExists { path: PathBuf },
|
||||
}
|
||||
|
||||
/// The kind of entity involved in a not-found error.
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum EntityType {
|
||||
Reference,
|
||||
Library,
|
||||
Annotation,
|
||||
Snapshot,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for EntityType {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
EntityType::Reference => write!(f, "Reference"),
|
||||
EntityType::Library => write!(f, "Library"),
|
||||
EntityType::Annotation => write!(f, "Annotation"),
|
||||
EntityType::Snapshot => write!(f, "Snapshot"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Business logic validation errors.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum ValidationError {
|
||||
#[error(
|
||||
"library cycle detected: moving library {library_id} under {parent_id} would create a cycle"
|
||||
)]
|
||||
LibraryCycle {
|
||||
library_id: String,
|
||||
parent_id: String,
|
||||
},
|
||||
|
||||
#[error("library {id} has children and cannot be deleted; delete or move children first")]
|
||||
LibraryHasChildren { id: String },
|
||||
|
||||
#[error("cite key already exists: {cite_key}")]
|
||||
DuplicateCiteKey { cite_key: String },
|
||||
|
||||
#[error("cite key cannot be empty")]
|
||||
EmptyCiteKey,
|
||||
|
||||
#[error("library name cannot be empty")]
|
||||
EmptyLibraryName,
|
||||
|
||||
#[error("reference {reference_id} has no PDF attached")]
|
||||
NoPdfAttached { reference_id: String },
|
||||
|
||||
#[error("PDF file not found: {path}")]
|
||||
PdfNotFound { path: PathBuf },
|
||||
|
||||
#[error("there are uncommitted changes; create a snapshot or call discard_changes() first")]
|
||||
UncommittedChanges,
|
||||
}
|
||||
|
||||
/// Errors specific to BibTeX export.
|
||||
#[derive(Debug, Error)]
|
||||
pub enum BibtexError {
|
||||
#[error("reference '{cite_key}' ({entry_type}): missing required field '{field}'")]
|
||||
MissingRequiredField {
|
||||
cite_key: String,
|
||||
entry_type: String,
|
||||
field: String,
|
||||
},
|
||||
}
|
||||
Reference in New Issue
Block a user