ic_dbms_api/memory/
error.rs1use std::array::TryFromSliceError;
2
3use candid::CandidType;
4use serde::{Deserialize, Serialize};
5use thiserror::Error;
6
7use crate::memory::{Page, PageOffset};
8
9#[derive(Debug, Error, CandidType, Deserialize, Serialize)]
11pub enum MemoryError {
12 #[error("Data too large for page (page size: {page_size}, requested: {requested})")]
14 DataTooLarge { page_size: u64, requested: u64 },
15 #[error("Failed to decode data from bytes: {0}")]
17 DecodeError(DecodeError),
18 #[error("Failed to allocate a new page")]
20 FailedToAllocatePage,
21 #[error("Offset {offset} is not aligned to {alignment} bytes")]
22 OffsetNotAligned { offset: PageOffset, alignment: u16 },
23 #[error("Stable memory access out of bounds")]
25 OutOfBounds,
26 #[error(
28 "Tried to read or write out of the allocated page (page: {page}, offset: {offset}, data size: {data_size}, page size: {page_size})"
29 )]
30 SegmentationFault {
31 page: Page,
32 offset: PageOffset,
33 data_size: u64,
34 page_size: u64,
35 },
36 #[error("Failed to grow stable memory: {0}")]
38 StableMemoryError(String),
39}
40
41impl From<ic_cdk::stable::StableMemoryError> for MemoryError {
42 fn from(err: ic_cdk::stable::StableMemoryError) -> Self {
43 MemoryError::StableMemoryError(err.to_string())
44 }
45}
46
47impl From<TryFromSliceError> for MemoryError {
48 fn from(err: TryFromSliceError) -> Self {
49 MemoryError::DecodeError(DecodeError::from(err))
50 }
51}
52
53impl From<std::string::FromUtf8Error> for MemoryError {
54 fn from(err: std::string::FromUtf8Error) -> Self {
55 MemoryError::DecodeError(DecodeError::from(err))
56 }
57}
58
59impl From<candid::types::principal::PrincipalError> for MemoryError {
60 fn from(err: candid::types::principal::PrincipalError) -> Self {
61 MemoryError::DecodeError(DecodeError::from(err))
62 }
63}
64
65impl From<uuid::Error> for MemoryError {
66 fn from(err: uuid::Error) -> Self {
67 MemoryError::DecodeError(DecodeError::from(err))
68 }
69}
70
71#[derive(Debug, Error, CandidType, Deserialize, Serialize)]
73pub enum DecodeError {
74 #[error("Bad raw record header")]
76 BadRawRecordHeader,
77 #[error("Invalid JSON: {0}")]
79 InvalidJson(String),
80 #[error("Principal error: {0}")]
82 PrincipalError(String),
83 #[error("Failed to convert from slice: {0}")]
85 TryFromSliceError(String),
86 #[error("Failed to convert from UTF-8 string: {0}")]
88 Utf8Error(String),
89 #[error("Data too short to decode")]
91 TooShort,
92 #[error("UUID error: {0}")]
94 UuidError(String),
95}
96
97impl From<uuid::Error> for DecodeError {
98 fn from(err: uuid::Error) -> Self {
99 DecodeError::UuidError(err.to_string())
100 }
101}
102
103impl From<std::string::FromUtf8Error> for DecodeError {
104 fn from(err: std::string::FromUtf8Error) -> Self {
105 DecodeError::Utf8Error(err.to_string())
106 }
107}
108
109impl From<TryFromSliceError> for DecodeError {
110 fn from(err: TryFromSliceError) -> Self {
111 DecodeError::TryFromSliceError(err.to_string())
112 }
113}
114
115impl From<candid::types::principal::PrincipalError> for DecodeError {
116 fn from(err: candid::types::principal::PrincipalError) -> Self {
117 DecodeError::PrincipalError(err.to_string())
118 }
119}
120
121#[cfg(test)]
122mod tests {
123
124 use super::*;
125
126 #[test]
127 fn test_memory_error_display() {
128 let error = MemoryError::DataTooLarge {
129 page_size: 1024,
130 requested: 2048,
131 };
132 assert_eq!(
133 format!("{}", error),
134 "Data too large for page (page size: 1024, requested: 2048)"
135 );
136 }
137
138 #[test]
139 fn test_decode_error_display() {
140 let error = DecodeError::BadRawRecordHeader;
141 assert_eq!(format!("{}", error), "Bad raw record header");
142 }
143}