Skip to main content

OAuthError

Enum OAuthError 

Source
pub enum OAuthError {
    InvalidHmac,
    StateMismatch {
        expected: String,
        received: String,
    },
    TokenExchangeFailed {
        status: u16,
        message: String,
    },
    ClientCredentialsFailed {
        status: u16,
        message: String,
    },
    TokenRefreshFailed {
        status: u16,
        message: String,
    },
    InvalidCallback {
        reason: String,
    },
    MissingHostConfig,
    InvalidJwt {
        reason: String,
    },
    NotEmbeddedApp,
    NotPrivateApp,
    HttpError(HttpError),
}
Expand description

Errors that can occur during OAuth operations.

This enum covers all failure modes in OAuth flows, including the authorization code flow, token exchange, client credentials, token refresh, and JWT validation for embedded apps.

§Thread Safety

OAuthError is Send + Sync, making it safe to use across async boundaries.

§Example

use shopify_sdk::auth::oauth::OAuthError;

fn handle_oauth_error(err: OAuthError) {
    match err {
        OAuthError::InvalidHmac => {
            eprintln!("Security: HMAC validation failed");
        }
        OAuthError::StateMismatch { expected, received } => {
            eprintln!("CSRF: State mismatch - expected {}, got {}", expected, received);
        }
        OAuthError::TokenExchangeFailed { status, message } => {
            eprintln!("Token exchange failed ({}): {}", status, message);
        }
        OAuthError::ClientCredentialsFailed { status, message } => {
            eprintln!("Client credentials failed ({}): {}", status, message);
        }
        OAuthError::TokenRefreshFailed { status, message } => {
            eprintln!("Token refresh failed ({}): {}", status, message);
        }
        OAuthError::InvalidCallback { reason } => {
            eprintln!("Invalid callback: {}", reason);
        }
        OAuthError::MissingHostConfig => {
            eprintln!("Configuration error: Host URL not configured");
        }
        OAuthError::InvalidJwt { reason } => {
            eprintln!("JWT validation failed: {}", reason);
        }
        OAuthError::NotEmbeddedApp => {
            eprintln!("Token exchange only works for embedded apps");
        }
        OAuthError::NotPrivateApp => {
            eprintln!("Client credentials only works for private apps");
        }
        OAuthError::HttpError(e) => {
            eprintln!("HTTP error: {}", e);
        }
    }
}

Variants§

§

InvalidHmac

HMAC signature validation failed.

This indicates the callback request’s HMAC signature does not match the expected value computed with the API secret key. This could indicate a tampered request or misconfigured secret key.

§

StateMismatch

OAuth state parameter mismatch.

The state parameter in the callback does not match the expected state that was generated during begin_auth(). This is a security measure against CSRF attacks.

Fields

§expected: String

The expected state value that was generated.

§received: String

The state value received in the callback.

§

TokenExchangeFailed

Token exchange request failed.

The POST request to exchange the authorization code for an access token returned a non-success HTTP status.

Fields

§status: u16

The HTTP status code returned.

§message: String

The error message from the response.

§

ClientCredentialsFailed

Client credentials exchange request failed.

The POST request to obtain an access token using client credentials returned a non-success HTTP status. This error is specific to the Client Credentials Grant flow used by private/organization apps.

§Example

use shopify_sdk::auth::oauth::OAuthError;

let error = OAuthError::ClientCredentialsFailed {
    status: 401,
    message: "Invalid client credentials".to_string(),
};
assert!(error.to_string().contains("Client credentials"));
assert!(error.to_string().contains("401"));

Fields

§status: u16

The HTTP status code returned (0 for network errors).

§message: String

The error message from the response or network error description.

§

TokenRefreshFailed

Token refresh or migration request failed.

The POST request to refresh an access token or migrate to expiring tokens returned a non-success HTTP status. This error is used for both the refresh_access_token and migrate_to_expiring_token functions.

§Example

use shopify_sdk::auth::oauth::OAuthError;

let error = OAuthError::TokenRefreshFailed {
    status: 400,
    message: "Invalid refresh token".to_string(),
};
assert!(error.to_string().contains("Token refresh"));
assert!(error.to_string().contains("400"));

Fields

§status: u16

The HTTP status code returned (0 for network errors).

§message: String

The error message from the response or network error description.

§

InvalidCallback

Callback parameters are invalid or malformed.

One or more parameters in the OAuth callback are missing, empty, or have invalid formats.

Fields

§reason: String

Description of what’s invalid about the callback.

§

MissingHostConfig

Host URL is not configured in ShopifyConfig.

The begin_auth() function requires a host URL to construct the redirect URI. Configure this via ShopifyConfigBuilder::host().

§

InvalidJwt

JWT validation failed.

This error occurs during token exchange when the session token (JWT) provided by App Bridge cannot be validated. Common causes include:

  • Token is expired or not yet valid
  • Token was signed with a different secret key
  • Token’s audience (aud) claim doesn’t match the app’s API key
  • Token structure is malformed
  • Shopify rejected the token during token exchange

§Example

use shopify_sdk::auth::oauth::OAuthError;

let error = OAuthError::InvalidJwt {
    reason: "Session token had invalid API key".to_string(),
};
assert!(error.to_string().contains("Invalid JWT"));

Fields

§reason: String

Description of why the JWT validation failed.

§

NotEmbeddedApp

Token exchange requires an embedded app configuration.

Token exchange OAuth flow is only available for embedded apps that receive session tokens from Shopify App Bridge. Ensure that ShopifyConfigBuilder::is_embedded(true) is set.

§Example

use shopify_sdk::auth::oauth::OAuthError;

let error = OAuthError::NotEmbeddedApp;
assert!(error.to_string().contains("embedded app"));
§

NotPrivateApp

Client credentials requires a non-embedded app configuration.

Client Credentials Grant OAuth flow is only available for private or organization apps that are NOT embedded in the Shopify admin. Ensure that ShopifyConfigBuilder::is_embedded(false) is set (or not set, as false is the default).

This error is the inverse of NotEmbeddedApp, which is used for token exchange flows that require embedded apps.

§Example

use shopify_sdk::auth::oauth::OAuthError;

let error = OAuthError::NotPrivateApp;
assert!(error.to_string().contains("non-embedded"));
§

HttpError(HttpError)

Wrapped HTTP client error.

An error occurred during HTTP communication, such as a network failure or request validation error.

Trait Implementations§

Source§

impl Debug for OAuthError

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for OAuthError

Source§

fn fmt(&self, __formatter: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Error for OAuthError

Source§

fn source(&self) -> Option<&(dyn Error + 'static)>

Returns the lower-level source of this error, if any. Read more
1.0.0 · Source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · Source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
Source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type-based access to context intended for error reports. Read more
Source§

impl From<HttpError> for OAuthError

Source§

fn from(source: HttpError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more