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