use thiserror::Error;
use std::any::TypeId;
#[derive(Error, Debug, Clone)]
pub enum ConversionError {
#[error("不支持的步骤类型: {step_type} (TypeId: {type_id:?})")]
UnsupportedStepType { step_type: String, type_id: TypeId },
#[error("步骤验证失败: {reason}, 步骤: {step_name}")]
ValidationFailed { step_name: String, reason: String },
#[error("Yrs 事务操作失败: {operation}, 原因: {reason}")]
YrsTransactionFailed { operation: String, reason: String },
#[error("节点操作失败: {node_id}, 操作: {operation}, 原因: {reason}")]
NodeOperationFailed { node_id: String, operation: String, reason: String },
#[error("属性操作失败: 节点 {node_id}, 属性 {attr_key}, 原因: {reason}")]
AttributeOperationFailed {
node_id: String,
attr_key: String,
reason: String,
},
#[error(
"标记操作失败: 节点 {node_id}, 标记类型 {mark_type}, 原因: {reason}"
)]
MarkOperationFailed { node_id: String, mark_type: String, reason: String },
#[error("序列化失败: {reason}")]
SerializationFailed { reason: String },
#[error(
"权限不足: 用户 {user_id} 无法执行操作 {operation} 在节点 {node_id}"
)]
PermissionDenied { user_id: String, operation: String, node_id: String },
#[error(
"并发冲突: 节点 {node_id} 在客户端 {local_client} 和 {remote_client} 之间存在冲突"
)]
ConcurrencyConflict {
node_id: String,
local_client: String,
remote_client: String,
},
#[error("自定义错误: {message}")]
Custom { message: String },
}
impl ConversionError {
pub fn unsupported_step<T: 'static>(step_name: &str) -> Self {
Self::UnsupportedStepType {
step_type: step_name.to_string(),
type_id: TypeId::of::<T>(),
}
}
pub fn validation_failed(
step_name: &str,
reason: &str,
) -> Self {
Self::ValidationFailed {
step_name: step_name.to_string(),
reason: reason.to_string(),
}
}
pub fn node_operation_failed(
node_id: &str,
operation: &str,
reason: &str,
) -> Self {
Self::NodeOperationFailed {
node_id: node_id.to_string(),
operation: operation.to_string(),
reason: reason.to_string(),
}
}
pub fn permission_denied(
user_id: &str,
operation: &str,
node_id: &str,
) -> Self {
Self::PermissionDenied {
user_id: user_id.to_string(),
operation: operation.to_string(),
node_id: node_id.to_string(),
}
}
}
pub type ConversionResult<T> = Result<T, ConversionError>;
#[derive(Error, Debug, Clone)]
pub enum RecoverableError {
#[error("临时网络错误: {reason}")]
TemporaryNetworkError { reason: String },
#[error("资源暂时不可用: {resource}")]
ResourceTemporarilyUnavailable { resource: String },
#[error("事务冲突,可重试: {reason}")]
RetryableTransactionConflict { reason: String },
}
impl From<RecoverableError> for ConversionError {
fn from(err: RecoverableError) -> Self {
Self::Custom { message: err.to_string() }
}
}