Files
sausage/sdk/src/error.rs
T
SAU-317 implementer c54edea596
ci / check (push) Failing after 2m38s
Name the received JSON type in non-object params errors
Keep -32602 and existing validation order; tell callers to send the object itself.
Cover host routing, stdout fast paths, SDK calls and generated dispatch.

Card: SAU-317
2026-10-28 19:16:39 +00:00

62 lines
1.8 KiB
Rust

//! JSON-RPC failures and conversions from local errors.
use serde_json::Value;
/// An SDK operation that can fail.
pub type Result<T> = std::result::Result<T, Error>;
/// A JSON-RPC failure.
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Error {
/// The JSON-RPC error code.
pub code: i64,
/// The diagnostic message.
pub message: String,
#[serde(skip_serializing_if = "Option::is_none")]
/// Optional structured error details.
pub data: Option<Value>,
}
impl Error {
/// Build the object-params diagnostic used by calls and generated dispatch.
#[doc(hidden)]
pub fn params_not_object(params: &Value) -> Self {
let kind = match params {
Value::String(_) => "a string",
Value::Array(_) => "an array",
Value::Number(_) => "a number",
Value::Null => "null",
Value::Bool(_) => "a boolean",
Value::Object(_) => "an object",
};
Self::new(
-32602,
format!(
"params must be a JSON object, got {kind}. Send the object itself, not a JSON-encoded string."
),
)
}
/// Construct an error without structured details.
pub fn new(code: i64, message: impl Into<String>) -> Self {
Self {
code,
message: message.into(),
data: None,
}
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(&self.message)
}
}
impl std::error::Error for Error {}
impl From<std::io::Error> for Error {
fn from(e: std::io::Error) -> Self {
Self::new(-32603, e.to_string())
}
}
impl From<serde_json::Error> for Error {
fn from(e: serde_json::Error) -> Self {
Self::new(-32603, e.to_string())
}
}