Skip to main content

lingxia_lxapp/
error.rs

1use lingxia_platform::PlatformError;
2#[cfg(feature = "js-appservice")]
3use rong::RongJSError;
4#[cfg(feature = "js-appservice")]
5use rong::error::{ErrorData, ErrorNumber};
6use serde_json::Value;
7use std::io;
8use thiserror::Error;
9
10#[derive(Debug, Clone, Error)]
11pub enum LxAppError {
12    /// Error when performing web operations
13    #[error("WebView error: {0}")]
14    WebView(String),
15
16    #[error("{0} not found")]
17    ResourceNotFound(String),
18
19    #[error("{0} is not valid JSON file")]
20    InvalidJsonFile(String),
21
22    /// Error for invalid parameters
23    #[error("Invalid parameter: {0}")]
24    InvalidParameter(String),
25
26    /// Error for unsupported operations
27    #[error("Unsupported operation: {0}")]
28    UnsupportedOperation(String),
29
30    /// The lxapp already owns a live presentation in another shell region.
31    #[error("Surface conflict: {0}")]
32    SurfaceConflict(String),
33
34    /// Error for I/O operations (file access, network, etc.)
35    #[error("I/O error: {0}")]
36    IoError(String),
37
38    /// Error for runtime operations
39    #[error("Runtime error: {0}")]
40    Runtime(String),
41
42    /// Error channel operations
43    #[error("Channel error: {0}")]
44    ChannelError(String),
45
46    /// Error when resource is exhausted
47    #[error("Resource exhausted: {0}")]
48    ResourceExhausted(String),
49
50    /// Error when bridge error
51    #[error("Bridge error: {0}")]
52    Bridge(String),
53
54    /// Error for Rong runtime
55    #[error("Rong Error: {0}")]
56    RongJS(String),
57
58    /// Structured Rong host error that preserves code/data metadata
59    #[error("{code}: {message}")]
60    RongJSHost {
61        code: String,
62        message: String,
63        data: Option<Value>,
64    },
65
66    /// Error when plugin is not configured in lxapp.json
67    #[error("Plugin not configured: {0}")]
68    PluginNotConfigured(String),
69
70    /// Error when plugin download fails
71    #[error("Plugin download failed: {0}")]
72    PluginDownloadFailed(String),
73}
74
75impl From<io::Error> for LxAppError {
76    fn from(error: io::Error) -> Self {
77        LxAppError::IoError(error.to_string())
78    }
79}
80
81impl<T> From<std::sync::mpsc::SendError<T>> for LxAppError {
82    fn from(error: std::sync::mpsc::SendError<T>) -> Self {
83        LxAppError::ChannelError(error.to_string())
84    }
85}
86
87impl From<serde_json::Error> for LxAppError {
88    fn from(error: serde_json::Error) -> Self {
89        LxAppError::Bridge(format!("JSON Processing Error: {}", error))
90    }
91}
92
93#[cfg(feature = "js-appservice")]
94impl From<RongJSError> for LxAppError {
95    fn from(error: RongJSError) -> Self {
96        if let Some(host) = error.as_host_error() {
97            let data = host.data.as_ref().map(error_data_to_json);
98            return LxAppError::RongJSHost {
99                code: host.code.to_string(),
100                message: host.message.clone(),
101                data,
102            };
103        }
104        LxAppError::RongJS(error.to_string())
105    }
106}
107
108impl From<PlatformError> for LxAppError {
109    fn from(error: PlatformError) -> Self {
110        match error {
111            PlatformError::NotSupported(message) => LxAppError::UnsupportedOperation(message),
112            other => LxAppError::Runtime(other.to_string()),
113        }
114    }
115}
116
117impl From<lingxia_update::UpdateError> for LxAppError {
118    fn from(error: lingxia_update::UpdateError) -> Self {
119        match error {
120            lingxia_update::UpdateError::InvalidParameter(detail) => {
121                LxAppError::InvalidParameter(detail)
122            }
123            lingxia_update::UpdateError::UnsupportedOperation(detail) => {
124                LxAppError::UnsupportedOperation(detail)
125            }
126            lingxia_update::UpdateError::ResourceNotFound(detail) => {
127                LxAppError::ResourceNotFound(detail)
128            }
129            lingxia_update::UpdateError::Io(detail) => LxAppError::IoError(detail),
130            lingxia_update::UpdateError::Runtime(detail) => LxAppError::Runtime(detail),
131        }
132    }
133}
134
135impl From<lingxia_settings::SettingsError> for LxAppError {
136    fn from(error: lingxia_settings::SettingsError) -> Self {
137        LxAppError::Runtime(error.to_string())
138    }
139}
140
141#[cfg(feature = "js-appservice")]
142fn error_data_to_json(data: &ErrorData) -> Value {
143    match data {
144        ErrorData::Null => Value::Null,
145        ErrorData::Bool(v) => Value::Bool(*v),
146        ErrorData::String(v) => Value::String(v.clone()),
147        ErrorData::Number(n) => match n {
148            ErrorNumber::I64(v) => Value::Number(serde_json::Number::from(*v)),
149            ErrorNumber::U64(v) => Value::Number(serde_json::Number::from(*v)),
150            ErrorNumber::F64(bits) => {
151                let num = f64::from_bits(*bits);
152                match serde_json::Number::from_f64(num) {
153                    Some(value) => Value::Number(value),
154                    None => Value::String(num.to_string()),
155                }
156            }
157        },
158        ErrorData::Array(items) => Value::Array(items.iter().map(error_data_to_json).collect()),
159        ErrorData::Object(obj) => Value::Object(
160            obj.iter()
161                .map(|(k, v)| (k.clone(), error_data_to_json(v)))
162                .collect(),
163        ),
164    }
165}