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("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("Invalid parameter: {0}")]
24 InvalidParameter(String),
25
26 #[error("Unsupported operation: {0}")]
28 UnsupportedOperation(String),
29
30 #[error("I/O error: {0}")]
32 IoError(String),
33
34 #[error("Runtime error: {0}")]
36 Runtime(String),
37
38 #[error("Channel error: {0}")]
40 ChannelError(String),
41
42 #[error("Resource exhausted: {0}")]
44 ResourceExhausted(String),
45
46 #[error("Bridge error: {0}")]
48 Bridge(String),
49
50 #[error("Rong Error: {0}")]
52 RongJS(String),
53
54 #[error("{code}: {message}")]
56 RongJSHost {
57 code: String,
58 message: String,
59 data: Option<Value>,
60 },
61
62 #[error("Plugin not configured: {0}")]
64 PluginNotConfigured(String),
65
66 #[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}