mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
* chore: load plugin * chore: sidecar * chore: fix test * chore: clippy * chore: save chat config * chore: arc plugin * chore: add plugins * chore: clippy * chore: test streaming * chore: config chat * chore: stream message * chore: response with local ai * chore: fix compile * chore: config ui * chore: fix load plugin * chore: add docs * chore: update docs * chore: disable local ai * chore: fix compile * chore: clippy
175 lines
4.7 KiB
Rust
175 lines
4.7 KiB
Rust
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
|
use serde_json::{json, Value as JsonValue};
|
|
use std::{fmt, io};
|
|
|
|
/// The error type of `tauri-utils`.
|
|
#[derive(Debug, thiserror::Error)]
|
|
pub enum SidecarError {
|
|
/// An IO error occurred on the underlying communication channel.
|
|
#[error(transparent)]
|
|
Io(#[from] io::Error),
|
|
/// The peer returned an error.
|
|
#[error("Remote error: {0}")]
|
|
RemoteError(RemoteError),
|
|
/// The peer closed the connection.
|
|
#[error("Peer closed the connection.")]
|
|
PeerDisconnect,
|
|
/// The peer sent a response containing the id, but was malformed.
|
|
#[error("Invalid response.")]
|
|
InvalidResponse,
|
|
|
|
#[error(transparent)]
|
|
Internal(#[from] anyhow::Error),
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum ReadError {
|
|
/// An error occurred in the underlying stream
|
|
Io(io::Error),
|
|
/// The message was not valid JSON.
|
|
Json(serde_json::Error),
|
|
/// The message was not a JSON object.
|
|
NotObject(String),
|
|
/// The the method and params were not recognized by the handler.
|
|
UnknownRequest(serde_json::Error),
|
|
/// The peer closed the connection.
|
|
Disconnect,
|
|
}
|
|
|
|
#[derive(Debug, Clone, thiserror::Error)]
|
|
pub enum RemoteError {
|
|
/// The JSON was valid, but was not a correctly formed request.
|
|
///
|
|
/// This Error is used internally, and should not be returned by
|
|
/// clients.
|
|
#[error("Invalid request: {0:?}")]
|
|
InvalidRequest(Option<JsonValue>),
|
|
|
|
#[error("Invalid response: {0}")]
|
|
InvalidResponse(JsonValue),
|
|
|
|
#[error("Parse response: {0}")]
|
|
ParseResponse(JsonValue),
|
|
/// A custom error, defined by the client.
|
|
#[error("Custom error: {message}")]
|
|
Custom {
|
|
code: i64,
|
|
message: String,
|
|
data: Option<JsonValue>,
|
|
},
|
|
/// An error that cannot be represented by an error object.
|
|
///
|
|
/// This error is intended to accommodate clients that return arbitrary
|
|
/// error values. It should not be used for new errors.
|
|
#[error("Unknown error: {0}")]
|
|
Unknown(JsonValue),
|
|
}
|
|
|
|
impl ReadError {
|
|
/// Returns `true` iff this is the `ReadError::Disconnect` variant.
|
|
pub fn is_disconnect(&self) -> bool {
|
|
matches!(*self, ReadError::Disconnect)
|
|
}
|
|
}
|
|
|
|
impl fmt::Display for ReadError {
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
match self {
|
|
ReadError::Io(ref err) => write!(f, "I/O Error: {:?}", err),
|
|
ReadError::Json(ref err) => write!(f, "JSON Error: {:?}", err),
|
|
ReadError::NotObject(s) => write!(f, "Expected JSON object, found: {}", s),
|
|
ReadError::UnknownRequest(ref err) => write!(f, "Unknown request: {:?}", err),
|
|
ReadError::Disconnect => write!(f, "Peer closed the connection."),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<serde_json::Error> for ReadError {
|
|
fn from(err: serde_json::Error) -> ReadError {
|
|
ReadError::Json(err)
|
|
}
|
|
}
|
|
|
|
impl From<io::Error> for ReadError {
|
|
fn from(err: io::Error) -> ReadError {
|
|
ReadError::Io(err)
|
|
}
|
|
}
|
|
|
|
impl From<serde_json::Error> for RemoteError {
|
|
fn from(err: serde_json::Error) -> RemoteError {
|
|
RemoteError::InvalidRequest(Some(json!(err.to_string())))
|
|
}
|
|
}
|
|
|
|
impl From<RemoteError> for SidecarError {
|
|
fn from(err: RemoteError) -> SidecarError {
|
|
SidecarError::RemoteError(err)
|
|
}
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize)]
|
|
struct ErrorHelper {
|
|
code: i64,
|
|
message: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
data: Option<JsonValue>,
|
|
}
|
|
|
|
impl<'de> Deserialize<'de> for RemoteError {
|
|
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
{
|
|
let v = JsonValue::deserialize(deserializer)?;
|
|
let resp = match ErrorHelper::deserialize(&v) {
|
|
Ok(resp) => resp,
|
|
Err(_) => return Ok(RemoteError::Unknown(v)),
|
|
};
|
|
|
|
Ok(match resp.code {
|
|
-32600 => RemoteError::InvalidRequest(resp.data),
|
|
_ => RemoteError::Custom {
|
|
code: resp.code,
|
|
message: resp.message,
|
|
data: resp.data,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
impl Serialize for RemoteError {
|
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
|
where
|
|
S: Serializer,
|
|
{
|
|
let (code, message, data) = match self {
|
|
RemoteError::InvalidRequest(ref d) => (-32600, "Invalid request".to_string(), d.clone()),
|
|
RemoteError::Custom {
|
|
code,
|
|
ref message,
|
|
ref data,
|
|
} => (*code, message.clone(), data.clone()),
|
|
RemoteError::Unknown(_) => {
|
|
panic!("The 'Unknown' error variant is not intended for client use.")
|
|
},
|
|
RemoteError::InvalidResponse(resp) => (
|
|
-1,
|
|
"Invalid response".to_string(),
|
|
Some(json!(resp.to_string())),
|
|
),
|
|
RemoteError::ParseResponse(resp) => (
|
|
-1,
|
|
"Invalid response".to_string(),
|
|
Some(json!(resp.to_string())),
|
|
),
|
|
};
|
|
let err = ErrorHelper {
|
|
code,
|
|
message,
|
|
data,
|
|
};
|
|
err.serialize(serializer)
|
|
}
|
|
}
|