Skip to main content

world_id_authenticator/
error.rs

1use reqwest::StatusCode;
2use world_id_primitives::{PrimitiveError, ValidationError};
3use world_id_proof::ProofError;
4
5/// Errors that can occur when interacting with the Authenticator.
6#[derive(Debug, thiserror::Error)]
7pub enum AuthenticatorError {
8    /// Primitive error
9    #[error(transparent)]
10    PrimitiveError(#[from] PrimitiveError),
11
12    /// This operation requires a registered account and an account is not registered
13    /// for this authenticator. Call `create_account` first to register it.
14    #[error("Account is not registered for this authenticator.")]
15    AccountDoesNotExist,
16
17    /// An error occurred while interacting with the EVM contract.
18    #[error("Error interacting with EVM contract: {0}")]
19    ContractError(#[from] alloy::contract::Error),
20
21    /// Network/HTTP request error.
22    #[error("Network error: {0}")]
23    NetworkError(#[from] reqwest::Error),
24
25    /// Public key not found in the Authenticator public key set. Usually indicates the local state is out of sync with the registry.
26    #[error("Public key not found.")]
27    PublicKeyNotFound,
28
29    /// Gateway returned an error response.
30    #[error("Gateway error (status {status}): {body}")]
31    GatewayError {
32        /// HTTP status code
33        status: StatusCode,
34        /// Response body
35        body: String,
36    },
37
38    /// Indexer returned an error response.
39    #[error("Indexer error (status {status}): {body}")]
40    IndexerError {
41        /// HTTP status code
42        status: StatusCode,
43        /// Response body
44        body: String,
45    },
46
47    /// Account creation timed out while polling for confirmation.
48    #[error("Account creation timed out")]
49    Timeout,
50
51    /// Configuration is invalid or missing required values.
52    #[error("Invalid configuration for {attribute}: {reason}")]
53    InvalidConfig {
54        /// The config attribute that is invalid.
55        attribute: String,
56        /// Description of why it is invalid.
57        reason: String,
58    },
59
60    /// The provided credential is not valid for the provided proof request.
61    #[error("The provided credential is not valid for the provided proof request")]
62    InvalidCredentialForProofRequest,
63
64    /// The provided credentials do not satisfy the proof request.
65    ///
66    /// This usually means the authenticator made an incorrect selection of credentials.
67    #[error("Proof request cannot be fulfilled with the provided credentials.")]
68    UnfullfilableRequest,
69
70    /// Used in Ownership Proofs. The provided `blinding_factor` does not match for the
71    /// provided `sub`, ownership cannot be proven.
72    #[error("the sub or blinding factor provided do not match the expected value.")]
73    InvalidSubOrBlindingFactor,
74
75    /// Error during the World ID registration process.
76    ///
77    /// This usually occurs from an on-chain revert.
78    #[error("Registration error ({error_code}): {error_message}")]
79    RegistrationError {
80        /// Error code from the registration process.
81        error_code: String,
82        /// Detailed error message.
83        error_message: String,
84    },
85
86    /// Error on proof generation
87    #[error(transparent)]
88    ProofError(#[from] ProofError),
89
90    /// Indexer returned an authenticator key slot that exceeds supported key capacity.
91    #[error(
92        "Invalid indexer authenticator pubkey slot {slot_index}; max supported slot is {max_supported_slot}"
93    )]
94    InvalidIndexerPubkeySlot {
95        /// Slot index returned by the indexer.
96        slot_index: usize,
97        /// Highest supported slot index.
98        max_supported_slot: usize,
99    },
100
101    /// OHTTP encapsulation or decapsulation error.
102    #[error("OHTTP encapsulation error: {0}")]
103    OhttpEncapsulationError(#[from] ohttp::Error),
104
105    /// Binary HTTP framing error.
106    #[error("Binary HTTP error: {0}")]
107    BhttpError(#[from] bhttp::Error),
108
109    /// The OHTTP relay itself returned a non-success status.
110    #[error("OHTTP relay error (status {status}): {body}")]
111    OhttpRelayError {
112        /// HTTP status code from the relay.
113        status: StatusCode,
114        /// Response body from the relay.
115        body: String,
116    },
117
118    /// A service returned a success status but the response body could not be
119    /// deserialized into the expected type.
120    #[error("Invalid service response: {0}")]
121    InvalidServiceResponse(String),
122
123    /// The assembled proof response failed self-validation against the request.
124    #[error(transparent)]
125    ResponseValidationError(#[from] ValidationError),
126
127    /// Proof materials not loaded. Call `with_proof_materials` before generating proofs.
128    #[error("Proof materials not loaded. Call `with_proof_materials` before generating proofs.")]
129    ProofMaterialsNotLoaded,
130
131    /// The session ID computed for this proof does not match the expected session ID from the proof request.
132    ///
133    /// This indicates the `session_id` provided by the RP is invalid or compromised, or
134    /// the authenticator cached the wrong `session_id_r_seed` for the `oprf_seed`.
135    #[error("the expected session id and the generated session id do not match")]
136    SessionIdMismatch,
137
138    /// Generic error for other unexpected issues.
139    #[error("{0}")]
140    Generic(String),
141}
142
143#[derive(Debug)]
144pub(crate) enum PollResult {
145    Retryable,
146    TerminalError(AuthenticatorError),
147}