Skip to main content

captcha_sdk/
error.rs

1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6use crate::ProviderId;
7
8/// Broad category for failures that prevent a verification result.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
10#[serde(rename_all = "snake_case")]
11#[non_exhaustive]
12pub enum VerificationErrorKind {
13    /// The adapter was configured incorrectly.
14    Configuration,
15    /// The provider could not be reached.
16    Transport,
17    /// The provider did not answer within the configured deadline.
18    Timeout,
19    /// The provider returned an unreadable or unsupported response.
20    InvalidResponse,
21    /// The provider adapter has not been implemented yet.
22    NotImplemented,
23}
24
25impl fmt::Display for VerificationErrorKind {
26    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
27        let value = match self {
28            Self::Configuration => "configuration",
29            Self::Transport => "transport",
30            Self::Timeout => "timeout",
31            Self::InvalidResponse => "invalid_response",
32            Self::NotImplemented => "not_implemented",
33        };
34        formatter.write_str(value)
35    }
36}
37
38/// Error raised when no normalized verification result can be produced.
39#[derive(Debug, Clone, PartialEq, Eq, Error)]
40#[error("{provider} verification failed ({kind}): {message}")]
41pub struct VerificationError {
42    /// Provider involved in the failed operation.
43    pub provider: ProviderId,
44    /// Machine-readable failure category.
45    pub kind: VerificationErrorKind,
46    /// Human-readable context that must not include secrets or tokens.
47    pub message: String,
48}
49
50impl VerificationError {
51    /// Creates a verification error.
52    pub fn new(
53        provider: ProviderId,
54        kind: VerificationErrorKind,
55        message: impl Into<String>,
56    ) -> Self {
57        Self {
58            provider,
59            kind,
60            message: message.into(),
61        }
62    }
63}