use thiserror::Error;
#[derive(Error, Debug)]
pub enum DebugError {
#[error("Probe not found: {0}")]
ProbeNotFound(String),
#[error("Target not supported: {0}")]
TargetNotSupported(String),
#[error("Connection failed: {0}")]
ConnectionFailed(String),
#[error("Invalid session ID: {0}")]
InvalidSession(String),
#[error("Session limit exceeded (max: {0})")]
SessionLimitExceeded(usize),
#[error("Operation timeout")]
OperationTimeout,
#[error("Invalid address: 0x{0:08x}")]
InvalidAddress(u64),
#[error("Memory access failed: {0}")]
MemoryAccessFailed(String),
#[error("Breakpoint limit exceeded")]
BreakpointLimitExceeded,
#[error("RTT not available")]
RttNotAvailable,
#[error("RTT error: {0}")]
RttError(String),
#[error("Flash operation failed: {0}")]
FlashOperationFailed(String),
#[error("Invalid configuration: {0}")]
InvalidConfig(String),
#[error("Probe error: {0}")]
ProbeError(String),
#[error("IO error: {0}")]
IoError(#[from] std::io::Error),
#[error("Serialization error: {0}")]
SerializationError(#[from] serde_json::Error),
#[error("Internal error: {0}")]
InternalError(String),
}
impl From<probe_rs::Error> for DebugError {
fn from(error: probe_rs::Error) -> Self {
DebugError::ProbeError(error.to_string())
}
}
impl From<anyhow::Error> for DebugError {
fn from(error: anyhow::Error) -> Self {
DebugError::InternalError(error.to_string())
}
}
pub type Result<T> = std::result::Result<T, DebugError>;
#[derive(Error, Debug)]
pub enum RttError {
#[error("Control block not found")]
ControlBlockNotFound,
#[error("Channel not found: {0}")]
ChannelNotFound(usize),
#[error("Buffer overflow")]
BufferOverflow,
#[error("Attach failed: {0}")]
AttachFailed(String),
#[error("Read timeout")]
ReadTimeout,
}
impl From<RttError> for DebugError {
fn from(error: RttError) -> Self {
DebugError::RttError(error.to_string())
}
}
#[derive(Error, Debug)]
pub enum TargetError {
#[error("Target not halted")]
TargetNotHalted,
#[error("Target not running")]
TargetNotRunning,
#[error("Reset failed: {0}")]
ResetFailed(String),
#[error("Halt failed: {0}")]
HaltFailed(String),
#[error("Step failed: {0}")]
StepFailed(String),
}
impl From<TargetError> for DebugError {
fn from(error: TargetError) -> Self {
DebugError::InternalError(error.to_string())
}
}
#[derive(Error, Debug)]
pub enum MemoryError {
#[error("Read failed at address 0x{address:08x}: {reason}")]
ReadFailed { address: u64, reason: String },
#[error("Write failed at address 0x{address:08x}: {reason}")]
WriteFailed { address: u64, reason: String },
#[error("Invalid memory range: 0x{start:08x}-0x{end:08x}")]
InvalidRange { start: u64, end: u64 },
#[error("Memory region not accessible: 0x{address:08x}")]
NotAccessible { address: u64 },
}
impl From<MemoryError> for DebugError {
fn from(error: MemoryError) -> Self {
DebugError::MemoryAccessFailed(error.to_string())
}
}
#[derive(Error, Debug)]
pub enum FlashError {
#[error("Flash erase failed: {0}")]
EraseFailed(String),
#[error("Flash program failed: {0}")]
ProgramFailed(String),
#[error("Flash verify failed: {0}")]
VerifyFailed(String),
#[error("Flash not writable")]
NotWritable,
#[error("Invalid flash address: 0x{0:08x}")]
InvalidAddress(u64),
}
impl From<FlashError> for DebugError {
fn from(error: FlashError) -> Self {
DebugError::FlashOperationFailed(error.to_string())
}
}