Skip to main content

sbpf_common/
errors.rs

1use {std::ops::Range, thiserror::Error};
2
3#[derive(Debug, Error)]
4pub enum SBPFError {
5    #[error("Bytecode error: {error}")]
6    BytecodeError {
7        error: String,
8        span: Range<usize>,
9        custom_label: Option<String>,
10    },
11}
12
13impl SBPFError {
14    pub fn label(&self) -> &str {
15        match self {
16            Self::BytecodeError { custom_label, .. } => {
17                custom_label.as_deref().unwrap_or("Bytecode error")
18            }
19        }
20    }
21
22    pub fn span(&self) -> &Range<usize> {
23        match self {
24            Self::BytecodeError { span, .. } => span,
25        }
26    }
27}
28
29#[derive(Error, Debug, Clone)]
30pub enum ExecutionError {
31    #[error("Division by zero")]
32    DivisionByZero,
33
34    #[error("Invalid operand")]
35    InvalidOperand,
36
37    #[error("Invalid instruction format")]
38    InvalidInstruction,
39
40    #[error("Call depth exceeded (max {0})")]
41    CallDepthExceeded(usize),
42
43    #[error("Invalid memory access at address {0:#x}")]
44    InvalidMemoryAccess(u64),
45
46    #[error("Syscall error: {0}")]
47    SyscallError(String),
48}
49
50#[cfg(test)]
51mod tests {
52    use super::*;
53
54    #[test]
55    fn test_bytecode_error() {
56        let error = SBPFError::BytecodeError {
57            error: "Invalid opcode".to_string(),
58            span: 10..20,
59            custom_label: Some("Custom error message".to_string()),
60        };
61
62        assert_eq!(error.label(), "Custom error message");
63        assert_eq!(error.span(), &(10..20));
64        assert_eq!(error.to_string(), "Bytecode error: Invalid opcode");
65    }
66}