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}