1use core::fmt;
2
3use serde::{Deserialize, Serialize};
4
5pub const WEATHERKIT_BRIDGE_ERROR_DOMAIN: &str = "WeatherKitBridge";
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct WeatherKitError {
9 pub domain: String,
10 pub code: i64,
11 pub message: String,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub(crate) struct ErrorPayload {
17 pub domain: String,
18 pub code: i64,
19 pub message: String,
20}
21
22impl WeatherKitError {
23 pub(crate) fn from_payload(payload: ErrorPayload) -> Self {
24 Self {
25 domain: payload.domain,
26 code: payload.code,
27 message: payload.message,
28 }
29 }
30
31 pub(crate) fn bridge(code: i64, message: impl Into<String>) -> Self {
32 Self {
33 domain: WEATHERKIT_BRIDGE_ERROR_DOMAIN.into(),
34 code,
35 message: message.into(),
36 }
37 }
38
39 pub fn is_entitlement_issue(&self) -> bool {
40 let domain = self.domain.to_ascii_lowercase();
41 let message = self.message.to_ascii_lowercase();
42 message.contains("entitlement")
43 || message.contains("permission")
44 || message.contains("bundle")
45 || message.contains("not authorized")
46 || message.contains("denied")
47 || domain.contains("jwtauthenticator")
48 || domain.contains("weatherdaemon")
49 || domain.contains("auth")
50 }
51}
52
53impl fmt::Display for WeatherKitError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "{} ({}) [{}]", self.message, self.code, self.domain)
56 }
57}
58
59impl std::error::Error for WeatherKitError {}