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    /// Error for I/O operations (file access, network, etc.)
31    #[error("I/O error: {0}")]
32    IoError(String),
33
34    /// Error for runtime operations
35    #[error("Runtime error: {0}")]
36    Runtime(String),
37
38    /// Error channel operations
39    #[error("Channel error: {0}")]
40    ChannelError(String),
41
42    /// Error when resource is exhausted
43    #[error("Resource exhausted: {0}")]
44    ResourceExhausted(String),
45
46    /// Error when bridge error
47    #[error("Bridge error: {0}")]
48    Bridge(String),
49
50    /// Error for Rong runtime
51    #[error("Rong Error: {0}")]
52    RongJS(String),
53
54    /// Structured Rong host error that preserves code/data metadata
55    #[error("{code}: {message}")]
56    RongJSHost {
57        code: String,
58        message: String,
59        data: Option<Value>,
60    },
61
62    /// Error when plugin is not configured in lxapp.json
63    #[error("Plugin not configured: {0}")]
64    PluginNotConfigured(String),
65
66    /// Error when plugin download fails
67    #[error("Plugin download failed: {0}")]
68    PluginDownloadFailed(String),
69}
70
71impl From<io::Error> for LxAppError {
72    fn from(error: io::Error) -> Self {
73        LxAppError::IoError(error.to_string())
74    }
75}
76
77impl<T> From<std::sync::mpsc::SendError<T>> for LxAppError {
78    fn from(error: std::sync::mpsc::SendError<T>) -> Self {
79        LxAppError::ChannelError(error.to_string())
80    }
81}
82
83impl From<serde_json::Error> for LxAppError {
84    fn from(error: serde_json::Error) -> Self {
85        LxAppError::Bridge(format!("JSON Processing Error: {}", error))
86    }
87}
88
89#[cfg(feature = "js-appservice")]
90impl From<RongJSError> for LxAppError {
91    fn from(error: RongJSError) -> Self {
92        if let Some(host) = error.as_host_error() {
93            let data = host.data.as_ref().map(error_data_to_json);
94            return LxAppError::RongJSHost {
95                code: host.code.to_string(),
96                message: host.message.clone(),
97                data,
98            };
99        }
100        LxAppError::RongJS(error.to_string())
101    }
102}
103
104impl From<PlatformError> for LxAppError {
105    fn from(error: PlatformError) -> Self {
106        match error {
107            PlatformError::NotSupported(message) => LxAppError::UnsupportedOperation(message),
108            other => LxAppError::Runtime(other.to_string()),
109        }
110    }
111}
112
113impl From<lingxia_update::UpdateError> for LxAppError {
114    fn from(error: lingxia_update::UpdateError) -> Self {
115        match error {
116            lingxia_update::UpdateError::InvalidParameter(detail) => {
117                LxAppError::InvalidParameter(detail)
118            }
119            lingxia_update::UpdateError::UnsupportedOperation(detail) => {
120                LxAppError::UnsupportedOperation(detail)
121            }
122            lingxia_update::UpdateError::ResourceNotFound(detail) => {
123                LxAppError::ResourceNotFound(detail)
124            }
125            lingxia_update::UpdateError::Io(detail) => LxAppError::IoError(detail),
126            lingxia_update::UpdateError::Runtime(detail) => LxAppError::Runtime(detail),
127        }
128    }
129}
130
131impl From<lingxia_settings::SettingsError> for LxAppError {
132    fn from(error: lingxia_settings::SettingsError) -> Self {
133        LxAppError::Runtime(error.to_string())
134    }
135}
136
137#[cfg(feature = "js-appservice")]
138fn error_data_to_json(data: &ErrorData) -> Value {
139    match data {
140        ErrorData::Null => Value::Null,
141        ErrorData::Bool(v) => Value::Bool(*v),
142        ErrorData::String(v) => Value::String(v.clone()),
143        ErrorData::Number(n) => match n {
144            ErrorNumber::I64(v) => Value::Number(serde_json::Number::from(*v)),
145            ErrorNumber::U64(v) => Value::Number(serde_json::Number::from(*v)),
146            ErrorNumber::F64(bits) => {
147                let num = f64::from_bits(*bits);
148                match serde_json::Number::from_f64(num) {
149                    Some(value) => Value::Number(value),
150                    None => Value::String(num.to_string()),
151                }
152            }
153        },
154        ErrorData::Array(items) => Value::Array(items.iter().map(error_data_to_json).collect()),
155        ErrorData::Object(obj) => Value::Object(
156            obj.iter()
157                .map(|(k, v)| (k.clone(), error_data_to_json(v)))
158                .collect(),
159        ),
160    }
161}