use crate::lsp_transport::RpcErrorPayload; use ra_mcp_domain::{fault::Fault, types::InvariantViolation}; use serde_json::Value; use thiserror::Error; /// Engine result type. pub type EngineResult = Result; /// Structured rust-analyzer response error. #[derive(Debug, Clone, Error)] #[error("lsp response error: code={code}, message={message}")] pub struct LspResponseError { /// LSP JSON-RPC error code. pub code: i64, /// LSP JSON-RPC error message. pub message: String, /// Optional JSON-RPC error data payload. pub data: Option, } /// Engine failure type. #[derive(Debug, Error)] pub enum EngineError { /// I/O failure while syncing source documents. #[error("io error: {0}")] Io(#[from] std::io::Error), /// Domain invariant was violated. #[error(transparent)] Invariant(#[from] InvariantViolation), /// Transport/process/protocol fault. #[error("engine fault: {0:?}")] Fault(Fault), /// rust-analyzer returned a JSON-RPC error object. #[error(transparent)] LspResponse(#[from] LspResponseError), /// Response payload could not be deserialized into expected type. #[error("invalid lsp payload for method {method}: {message}")] InvalidPayload { /// Request method. method: &'static str, /// Decoder error detail. message: String, }, /// Request params could not be serialized into JSON. #[error("invalid lsp request payload for method {method}: {message}")] InvalidRequest { /// Request method. method: &'static str, /// Encoder error detail. message: String, }, /// Path to URL conversion failed. #[error("path cannot be represented as file URL")] InvalidFileUrl, } impl From for EngineError { fn from(value: Fault) -> Self { Self::Fault(value) } } impl From for LspResponseError { fn from(value: RpcErrorPayload) -> Self { Self { code: value.code, message: value.message, data: value.data, } } } impl From for EngineError { fn from(value: RpcErrorPayload) -> Self { Self::LspResponse(value.into()) } }