tauri_plugin_notifications/
error.rs1use serde::{ser::Serializer, Serialize};
2
3pub type Result<T> = std::result::Result<T, Error>;
4
5#[cfg(desktop)]
7#[derive(Debug, thiserror::Error, Clone, serde::Deserialize)]
8pub struct ErrorResponse<T = ()> {
9 pub code: Option<String>,
11 pub message: Option<String>,
13 #[serde(flatten)]
15 pub data: T,
16}
17
18#[cfg(desktop)]
19impl<T> std::fmt::Display for ErrorResponse<T> {
20 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
21 if let Some(code) = &self.code {
22 write!(f, "[{code}]")?;
23 if self.message.is_some() {
24 write!(f, " - ")?;
25 }
26 }
27 if let Some(message) = &self.message {
28 write!(f, "{message}")?;
29 }
30 Ok(())
31 }
32}
33
34#[cfg(desktop)]
36#[derive(Debug, thiserror::Error)]
37pub enum PluginInvokeError {
38 #[error(transparent)]
40 InvokeRejected(#[from] ErrorResponse),
41 #[error("failed to deserialize response: {0}")]
43 CannotDeserializeResponse(serde_json::Error),
44 #[error("failed to serialize payload: {0}")]
46 CannotSerializePayload(serde_json::Error),
47}
48
49#[derive(Debug, thiserror::Error)]
50pub enum Error {
51 #[error(transparent)]
52 Io(#[from] std::io::Error),
53 #[cfg(mobile)]
54 #[error(transparent)]
55 PluginInvoke(#[from] tauri::plugin::mobile::PluginInvokeError),
56 #[cfg(desktop)]
57 #[error(transparent)]
58 PluginInvoke(#[from] crate::error::PluginInvokeError),
59}
60
61impl Serialize for Error {
62 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 serializer.serialize_str(self.to_string().as_ref())
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use super::*;
73 use std::io;
74
75 #[test]
76 fn test_io_error_conversion() {
77 let io_err = io::Error::new(io::ErrorKind::NotFound, "file not found");
78 let err: Error = io_err.into();
79 assert!(matches!(err, Error::Io(_)));
80 }
81
82 #[test]
83 fn test_io_error_serialization() {
84 let io_err = io::Error::new(io::ErrorKind::PermissionDenied, "access denied");
85 let err = Error::Io(io_err);
86 let json = serde_json::to_string(&err).expect("Failed to serialize IO error");
87 assert!(json.contains("access denied"));
88 }
89
90 #[test]
91 fn test_io_error_display() {
92 let io_err = io::Error::new(io::ErrorKind::NotFound, "test error");
93 let err = Error::Io(io_err);
94 let display_str = format!("{}", err);
95 assert!(display_str.contains("test error"));
96 }
97
98 #[cfg(mobile)]
99 #[test]
100 fn test_plugin_invoke_error_conversion() {
101 use tauri::plugin::mobile::PluginInvokeError;
102
103 let plugin_err = PluginInvokeError::MethodNotFound("test_method".to_string());
104 let err: Error = plugin_err.into();
105 assert!(matches!(err, Error::PluginInvoke(_)));
106 }
107
108 #[test]
109 fn test_result_type_err() {
110 let io_err = io::Error::other("test");
111 let result: Result<i32> = Err(Error::Io(io_err));
112 assert!(result.is_err());
113 }
114}