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("Principal error: {0}")]
79 PrincipalError(String),
80 #[error("Failed to convert from slice: {0}")]
82 TryFromSliceError(String),
83 #[error("Failed to convert from UTF-8 string: {0}")]
85 Utf8Error(String),
86 #[error("Data too short to decode")]
88 TooShort,
89 #[error("UUID error: {0}")]
91 UuidError(String),
92}
93
94impl From<uuid::Error> for DecodeError {
95 fn from(err: uuid::Error) -> Self {
96 DecodeError::UuidError(err.to_string())
97 }
98}
99
100impl From<std::string::FromUtf8Error> for DecodeError {
101 fn from(err: std::string::FromUtf8Error) -> Self {
102 DecodeError::Utf8Error(err.to_string())
103 }
104}
105
106impl From<TryFromSliceError> for DecodeError {
107 fn from(err: TryFromSliceError) -> Self {
108 DecodeError::TryFromSliceError(err.to_string())
109 }
110}
111
112impl From<candid::types::principal::PrincipalError> for DecodeError {
113 fn from(err: candid::types::principal::PrincipalError) -> Self {
114 DecodeError::PrincipalError(err.to_string())
115 }
116}
117
118#[cfg(test)]
119mod tests {
120
121 use super::*;
122
123 #[test]
124 fn test_memory_error_display() {
125 let error = MemoryError::DataTooLarge {
126 page_size: 1024,
127 requested: 2048,
128 };
129 assert_eq!(
130 format!("{}", error),
131 "Data too large for page (page size: 1024, requested: 2048)"
132 );
133 }
134
135 #[test]
136 fn test_decode_error_display() {
137 let error = DecodeError::BadRawRecordHeader;
138 assert_eq!(format!("{}", error), "Bad raw record header");
139 }
140}