automerge/
error.rs

1use crate::storage::load::Error as LoadError;
2use crate::types::{ActorId, ScalarValue};
3use crate::value::DataType;
4use crate::{ChangeHash, Cursor, LoadChangeError, ObjType, PatchAction};
5use hexane::PackError;
6use thiserror::Error;
7
8#[derive(Error, Debug)]
9pub enum AutomergeError {
10    #[error(transparent)]
11    ChangeGraph(#[from] crate::change_graph::MissingDep),
12    #[error("failed to load compressed data: {0}")]
13    Deflate(#[source] std::io::Error),
14    #[error("duplicate seq {0} found for actor {1}")]
15    DuplicateSeqNumber(u64, ActorId),
16    #[error("duplicate actor {0}: possible document clone")]
17    DuplicateActorId(ActorId),
18    #[error("general failure")]
19    Fail,
20    #[error("invalid actor ID `{0}`")]
21    InvalidActorId(String),
22    #[error("invalid actor index `{0}`")]
23    InvalidActorIndex(usize),
24    #[error(transparent)]
25    InvalidChangeHashBytes(#[from] InvalidChangeHashSlice),
26    #[error("invalid UTF-8 character at {0}")]
27    InvalidCharacter(usize),
28    #[error("invalid hash {0}")]
29    InvalidHash(ChangeHash),
30    #[error("index {0} is out of bounds")]
31    InvalidIndex(usize),
32    #[error("invalid obj id `{0}`")]
33    InvalidObjId(String),
34    #[error("invalid obj id format `{0}`")]
35    InvalidObjIdFormat(String),
36    #[error("invalid op for object of type `{0}`")]
37    InvalidOp(ObjType),
38    #[error("seq {0} is out of bounds")]
39    InvalidSeq(u64),
40    #[error("cursor {0} is invalid")]
41    InvalidCursor(Cursor),
42    #[error("op has no valid cursor")] // this error sucks
43    InvalidCursorOp,
44    #[error("cursor format is invalid")]
45    InvalidCursorFormat,
46    #[error("invalid type of value, expected `{expected}` but received `{unexpected}`")]
47    InvalidValueType {
48        expected: String,
49        unexpected: String,
50    },
51    #[error(transparent)]
52    Load(#[from] LoadError),
53    #[error(transparent)]
54    LoadChangeError(#[from] LoadChangeError),
55    #[error("increment operations must be against a counter value")]
56    MissingCounter,
57    #[error("hash {0} does not correspond to a change in this document")]
58    MissingHash(ChangeHash),
59    #[error("change's deps should already be in the document")]
60    MissingDeps,
61    #[error("compressed chunk was not a change")]
62    NonChangeCompressed,
63    #[error("id was not an object id")]
64    NotAnObject,
65    #[error(transparent)]
66    HydrateError(#[from] HydrateError),
67    #[error("patch logs cannot be shared between documents")]
68    PatchLogMismatch,
69    #[error(transparent)]
70    EncodingError(#[from] PackError),
71    #[error("failed to unbundle: {0}")]
72    Unbundle(Box<dyn std::error::Error + Send + Sync + 'static>),
73}
74
75impl PartialEq for AutomergeError {
76    fn eq(&self, other: &Self) -> bool {
77        std::mem::discriminant(self) == std::mem::discriminant(other)
78    }
79}
80
81#[cfg(feature = "wasm")]
82impl From<AutomergeError> for wasm_bindgen::JsValue {
83    fn from(err: AutomergeError) -> Self {
84        js_sys::Error::new(&std::format!("{}", err)).into()
85    }
86}
87
88#[derive(Error, Debug)]
89#[error("Invalid actor ID: {0}")]
90pub struct InvalidActorId(pub String);
91
92#[derive(Error, Debug, PartialEq)]
93#[error("Invalid scalar value, expected {expected} but received {unexpected}")]
94pub(crate) struct InvalidScalarValue {
95    pub(crate) raw_value: ScalarValue,
96    pub(crate) datatype: DataType,
97    pub(crate) unexpected: String,
98    pub(crate) expected: String,
99}
100
101#[derive(Error, Debug, Eq, PartialEq)]
102#[error("Invalid change hash slice: {0:?}")]
103pub struct InvalidChangeHashSlice(pub Vec<u8>);
104
105#[derive(Error, Debug, Eq, PartialEq)]
106#[error("Invalid object ID: {0}")]
107pub struct InvalidObjectId(pub String);
108
109#[derive(Error, Debug)]
110#[error("Invalid element ID: {0}")]
111pub struct InvalidElementId(pub String);
112
113#[derive(Error, Debug)]
114#[error("Invalid OpID: {0}")]
115pub struct InvalidOpId(pub String);
116
117#[derive(Error, Debug)]
118pub enum InvalidOpType {
119    #[error("unrecognized action index {0}")]
120    UnknownAction(u64),
121    #[error("non numeric argument for inc op")]
122    NonNumericInc,
123}
124
125#[derive(Error, Debug)]
126pub enum HydrateError {
127    //#[error(transparent)]
128    //ChangeGraph(#[from] crate::change_graph::MissingDep),
129    #[error("general failure")]
130    Fail,
131    #[error("invalid index {0} for sequence")]
132    InvalidIndex(usize),
133    #[error("invalid key {0} for map")]
134    InvalidKey(String),
135    #[error("increment of a non-counter")]
136    BadIncrement,
137    #[error("invalid op applied to map")]
138    InvalidMapOp,
139    #[error("invalid op appied to list")]
140    InvalidListOp,
141    #[error("invalid op applied to map: {0}")]
142    InvalidTextOp(PatchAction),
143    #[error("invalid prop in patch: {0}")]
144    ApplyInvalidProp(PatchAction),
145    #[error("invalid encoding for text value")]
146    InvalidEncoding,
147}
148
149#[derive(Error, Debug)]
150pub enum UpdateObjectError {
151    #[error("cannot change object type")]
152    ChangeType,
153    #[error(transparent)]
154    Automerge(#[from] AutomergeError),
155}