Skip to main content

weatherkit/
error.rs

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 {}