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("Surface conflict: {0}")]
32 SurfaceConflict(String),
33
34 #[error("I/O error: {0}")]
36 IoError(String),
37
38 #[error("Runtime error: {0}")]
40 Runtime(String),
41
42 #[error("Channel error: {0}")]
44 ChannelError(String),
45
46 #[error("Resource exhausted: {0}")]
48 ResourceExhausted(String),
49
50 #[error("Bridge error: {0}")]
52 Bridge(String),
53
54 #[error("Rong Error: {0}")]
56 RongJS(String),
57
58 #[error("{code}: {message}")]
60 RongJSHost {
61 code: String,
62 message: String,
63 data: Option<Value>,
64 },
65
66 #[error("Plugin not configured: {0}")]
68 PluginNotConfigured(String),
69
70 #[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}