use notedthat_core::{Error as CoreError, StorageError};
#[derive(Debug, thiserror::Error)]
pub enum WriteError {
#[error(transparent)]
Storage(StorageError),
#[error("payload too large: {size} bytes (limit {limit})")]
TooLarge {
size: u64,
limit: u64,
},
#[error(transparent)]
Path(CoreError),
#[error("indexer queue full during upsert")]
IndexerBackpressureUpsert,
#[error("indexer queue full during tombstone")]
IndexerBackpressureTombstone,
#[error("patch payload too large: {size} bytes (limit {limit})")]
PatchTooLarge {
size: u64,
limit: u64,
},
#[error("line range {first}..{last} out of range (total {total_lines} lines)")]
PatchLineOutOfRange {
first: u64,
last: u64,
total_lines: u64,
total_bytes: u64,
},
#[error("invalid patch request: {message}")]
PatchInvalidRange {
message: String,
},
#[error("replace: no match found for old_string")]
ReplaceNoMatch,
#[error("replace: found {count} matches; use replace_all to replace them all")]
ReplaceAmbiguous {
count: u64,
},
}
impl From<StorageError> for WriteError {
fn from(err: StorageError) -> Self {
Self::Storage(err)
}
}
#[cfg(test)]
mod tests {
use super::WriteError;
#[test]
fn patch_too_large_displays_size_limit_when_constructed() {
let err = WriteError::PatchTooLarge {
size: 200 * 1024 * 1024,
limit: 100 * 1024 * 1024,
};
assert!(err.to_string().contains("too large"));
}
#[test]
fn patch_line_out_of_range_constructs_with_line_and_byte_totals() {
let err = WriteError::PatchLineOutOfRange {
first: 999,
last: 1000,
total_lines: 20,
total_bytes: 100,
};
assert!(err.to_string().contains("out of range"));
}
#[test]
fn patch_invalid_range_displays_reason_when_constructed() {
let err = WriteError::PatchInvalidRange {
message: "test".into(),
};
assert!(err.to_string().contains("invalid patch"));
}
#[test]
fn replace_ambiguous_displays_match_count_when_constructed() {
let err = WriteError::ReplaceAmbiguous { count: 3 };
assert_eq!(
err.to_string(),
"replace: found 3 matches; use replace_all to replace them all"
);
}
}