use serde::{Deserialize, Serialize};
use thiserror::Error;
pub type Result<T> = std::result::Result<T, RobomotionError>;
#[derive(Error, Debug)]
pub enum RobomotionError {
#[error("Runtime not initialized")]
NotInitialized,
#[error("Node handler not found: {0}")]
HandlerNotFound(String),
#[error("Factory not found: {0}")]
FactoryNotFound(String),
#[error("Variable error: {0}")]
Variable(String),
#[error("Serialization error: {0}")]
Serialization(#[from] serde_json::Error),
#[error("IO error: {0}")]
Io(#[from] std::io::Error),
#[error("gRPC error: {0}")]
Grpc(#[from] tonic::Status),
#[error("gRPC transport error: {0}")]
Transport(#[from] tonic::transport::Error),
#[error("OAuth error: {0}")]
OAuth(String),
#[error("LMO error: {0}")]
Lmo(String),
#[error("Compression error: {0}")]
Compression(String),
#[error("{code}: {message}")]
Custom { code: String, message: String },
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct StructuredError {
pub code: String,
pub message: String,
}
impl StructuredError {
pub fn new(code: impl Into<String>, message: impl Into<String>) -> Self {
Self {
code: code.into(),
message: message.into(),
}
}
}
impl std::fmt::Display for StructuredError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match serde_json::to_string(self) {
Ok(json) => write!(f, "{}", json),
Err(_) => write!(f, "{}: {}", self.code, self.message),
}
}
}
impl std::error::Error for StructuredError {}
impl From<StructuredError> for RobomotionError {
fn from(err: StructuredError) -> Self {
RobomotionError::Custom {
code: err.code,
message: err.message,
}
}
}