ic_dbms_api/memory/
error.rs

1use std::array::TryFromSliceError;
2
3use thiserror::Error;
4
5use crate::memory::{MSize, Page, PageOffset};
6
7/// An enum representing possible memory-related errors.
8#[derive(Debug, Error)]
9pub enum MemoryError {
10    /// Error when the data to be written is too large for the page.
11    #[error("Data too large for page (page size: {page_size}, requested: {requested})")]
12    DataTooLarge { page_size: u64, requested: u64 },
13    /// Error when failing to decode data from bytes.
14    #[error("Failed to decode data from bytes: {0}")]
15    DecodeError(#[from] DecodeError),
16    /// Error when failing to allocate a new page.
17    #[error("Failed to allocate a new page")]
18    FailedToAllocatePage,
19    /// Error when attempting to access stable memory out of bounds.
20    #[error("Stable memory access out of bounds")]
21    OutOfBounds,
22    /// Error when attempting to write out of the allocated page.
23    #[error(
24        "Tried to write out of the allocated page (page: {page}, offset: {offset}, data size: {data_size}, page size: {page_size})"
25    )]
26    SegmentationFault {
27        page: Page,
28        offset: PageOffset,
29        data_size: MSize,
30        page_size: u64,
31    },
32    /// Error when failing to grow stable memory.
33    #[error("Failed to grow stable memory: {0}")]
34    StableMemoryError(#[from] ic_cdk::stable::StableMemoryError),
35}
36
37impl From<TryFromSliceError> for MemoryError {
38    fn from(err: TryFromSliceError) -> Self {
39        MemoryError::DecodeError(DecodeError::from(err))
40    }
41}
42
43impl From<std::string::FromUtf8Error> for MemoryError {
44    fn from(err: std::string::FromUtf8Error) -> Self {
45        MemoryError::DecodeError(DecodeError::from(err))
46    }
47}
48
49impl From<candid::types::principal::PrincipalError> for MemoryError {
50    fn from(err: candid::types::principal::PrincipalError) -> Self {
51        MemoryError::DecodeError(DecodeError::from(err))
52    }
53}
54
55impl From<uuid::Error> for MemoryError {
56    fn from(err: uuid::Error) -> Self {
57        MemoryError::DecodeError(DecodeError::from(err))
58    }
59}
60
61/// An enum representing possible decoding errors.
62#[derive(Debug, Error)]
63pub enum DecodeError {
64    /// Error when the raw record header is invalid.
65    #[error("Bad raw record header")]
66    BadRawRecordHeader,
67    /// Principal error
68    #[error("Principal error: {0}")]
69    PrincipalError(#[from] candid::types::principal::PrincipalError),
70    /// Error when failing to convert from slice.
71    #[error("Failed to convert from slice: {0}")]
72    TryFromSliceError(#[from] TryFromSliceError),
73    /// Error when failing to convert from UTF-8 string.
74    #[error("Failed to convert from UTF-8 string: {0}")]
75    Utf8Error(#[from] std::string::FromUtf8Error),
76    /// Error when the data is too short to decode.
77    #[error("Data too short to decode")]
78    TooShort,
79    /// UUID error
80    #[error("UUID error: {0}")]
81    UuidError(uuid::Error),
82}
83
84impl From<uuid::Error> for DecodeError {
85    fn from(err: uuid::Error) -> Self {
86        DecodeError::UuidError(err)
87    }
88}
89
90#[cfg(test)]
91mod tests {
92
93    use super::*;
94
95    #[test]
96    fn test_memory_error_display() {
97        let error = MemoryError::DataTooLarge {
98            page_size: 1024,
99            requested: 2048,
100        };
101        assert_eq!(
102            format!("{}", error),
103            "Data too large for page (page size: 1024, requested: 2048)"
104        );
105    }
106
107    #[test]
108    fn test_decode_error_display() {
109        let error = DecodeError::BadRawRecordHeader;
110        assert_eq!(format!("{}", error), "Bad raw record header");
111    }
112}