// SPDX-License-Identifier: Apache-2.0 // Copyright 2026 // //! Local error type for the Apple Sign-In auth provider. //! //! Mapped into [`kei_runtime_core::Error`] via `From` so the trait //! impls can use `?` against the runtime-core `Result`. use kei_runtime_core::DnaError; use thiserror::Error; /// Crate-local result alias. pub type Result = std::result::Result; /// Crate-local error variants. #[derive(Debug, Error)] pub enum Error { /// Transport / TLS / timeout failure from `reqwest`. #[error("http: {0}")] Http(#[from] reqwest::Error), /// Non-success HTTP status with the (best-effort) body text, or /// other Apple-side API protocol failure. #[error("api: {0}")] Api(String), /// id_token shape / base64 / utf8 / json failure during unverified decode. /// Only used in `#[cfg(test)]` paths; production uses [`Error::JwtVerify`]. #[error("jwt decode: {0}")] JwtDecode(String), /// ES256 signature verification against Apple JWKS failed, or a required /// claim (`iss`, `aud`, `exp`, `iat`) was invalid. #[error("jwt verify: {0}")] JwtVerify(String), /// id_token decoded but a required claim (e.g. `sub`) was missing. #[error("missing claim: {0}")] MissingClaim(String), /// DNA construction or parse failure. #[error("dna: {0}")] Dna(#[from] DnaError), /// Local IO (env var read, etc.). #[error("io: {0}")] Io(#[from] std::io::Error), /// JSON serialize / deserialize failure. #[error("serde: {0}")] Serde(#[from] serde_json::Error), } impl From for kei_runtime_core::Error { fn from(e: Error) -> Self { match e { Error::Http(re) => kei_runtime_core::Error::Network(re.to_string()), Error::Api(msg) => kei_runtime_core::Error::Provider(msg), Error::JwtDecode(msg) => { kei_runtime_core::Error::Provider(format!("jwt decode: {msg}")) } Error::JwtVerify(msg) => { kei_runtime_core::Error::Auth(format!("jwt verify: {msg}")) } Error::MissingClaim(c) => { kei_runtime_core::Error::Provider(format!("missing claim: {c}")) } Error::Dna(de) => kei_runtime_core::Error::Dna(de), Error::Io(io) => kei_runtime_core::Error::Io(io), Error::Serde(se) => kei_runtime_core::Error::Provider(format!("serde: {se}")), } } }