wasm_dbms_api/memory/
error.rs1use std::array::TryFromSliceError;
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6use crate::memory::{Page, PageOffset};
7
8#[cfg_attr(feature = "candid", derive(candid::CandidType))]
10#[derive(Debug, Error, Deserialize, Serialize)]
11pub enum MemoryError {
12 #[error("Autoincrement overflow: {0} column has reached its maximum value")]
14 AutoincrementOverflow(String),
15 #[error("Constraint violation: {0}")]
17 ConstraintViolation(String),
18 #[error("Data too large for page (page size: {page_size}, requested: {requested})")]
20 DataTooLarge { page_size: u64, requested: u64 },
21 #[error("Failed to decode data from bytes: {0}")]
23 DecodeError(DecodeError),
24 #[error("Failed to allocate a new page")]
26 FailedToAllocatePage,
27 #[error("Unclaimed pages ledger is full ({capacity} entries)")]
29 UnclaimedPagesFull {
30 capacity: u32,
32 },
33 #[error("Index not found for columns: {0:?}")]
35 IndexNotFound(Vec<String>),
36 #[error(
39 "Name hash collision: table `{candidate}` hashes to the same value as already-registered table `{existing}`"
40 )]
41 NameCollision {
42 candidate: String,
44 existing: String,
46 },
47 #[error("Entry not found in index")]
49 EntryNotFound,
50 #[error("Key too large: {size} bytes exceeds maximum {max} bytes")]
52 KeyTooLarge { size: u64, max: u64 },
53 #[error("Offset {offset} is not aligned to {alignment} bytes")]
54 OffsetNotAligned { offset: PageOffset, alignment: u16 },
55 #[error("Stable memory access out of bounds")]
57 OutOfBounds,
58 #[error(
60 "Tried to read or write out of the allocated page (page: {page}, offset: {offset}, data size: {data_size}, page size: {page_size})"
61 )]
62 SegmentationFault {
63 page: Page,
64 offset: PageOffset,
65 data_size: u64,
66 page_size: u64,
67 },
68 #[error("Memory provider error: {0}")]
70 ProviderError(String),
71}
72
73impl From<TryFromSliceError> for MemoryError {
74 fn from(err: TryFromSliceError) -> Self {
75 MemoryError::DecodeError(DecodeError::from(err))
76 }
77}
78
79impl From<std::string::FromUtf8Error> for MemoryError {
80 fn from(err: std::string::FromUtf8Error) -> Self {
81 MemoryError::DecodeError(DecodeError::from(err))
82 }
83}
84
85impl From<uuid::Error> for MemoryError {
86 fn from(err: uuid::Error) -> Self {
87 MemoryError::DecodeError(DecodeError::from(err))
88 }
89}
90
91#[cfg_attr(feature = "candid", derive(candid::CandidType))]
93#[derive(Debug, Error, Deserialize, Serialize)]
94pub enum DecodeError {
95 #[error("Bad raw record header")]
97 BadRawRecordHeader,
98 #[error("Invalid JSON: {0}")]
100 InvalidJson(String),
101 #[error("Identity decode error: {0}")]
103 IdentityDecodeError(String),
104 #[error("Failed to convert from slice: {0}")]
106 TryFromSliceError(String),
107 #[error("Failed to convert from UTF-8 string: {0}")]
109 Utf8Error(String),
110 #[error("Data too short to decode")]
112 TooShort,
113 #[error("Invalid discriminant: {0}")]
115 InvalidDiscriminant(u8),
116 #[error("UUID error: {0}")]
118 UuidError(String),
119}
120
121impl From<uuid::Error> for DecodeError {
122 fn from(err: uuid::Error) -> Self {
123 DecodeError::UuidError(err.to_string())
124 }
125}
126
127impl From<std::string::FromUtf8Error> for DecodeError {
128 fn from(err: std::string::FromUtf8Error) -> Self {
129 DecodeError::Utf8Error(err.to_string())
130 }
131}
132
133impl From<TryFromSliceError> for DecodeError {
134 fn from(err: TryFromSliceError) -> Self {
135 DecodeError::TryFromSliceError(err.to_string())
136 }
137}
138
139#[cfg(feature = "candid")]
140impl From<candid::types::principal::PrincipalError> for DecodeError {
141 fn from(err: candid::types::principal::PrincipalError) -> Self {
142 DecodeError::IdentityDecodeError(err.to_string())
143 }
144}
145
146#[cfg(test)]
147mod tests {
148
149 use super::*;
150
151 #[test]
152 fn test_memory_error_display() {
153 let error = MemoryError::DataTooLarge {
154 page_size: 1024,
155 requested: 2048,
156 };
157 assert_eq!(
158 format!("{}", error),
159 "Data too large for page (page size: 1024, requested: 2048)"
160 );
161 }
162
163 #[test]
164 fn test_decode_error_display() {
165 let error = DecodeError::BadRawRecordHeader;
166 assert_eq!(format!("{}", error), "Bad raw record header");
167 }
168}