BridgeError

Enum BridgeError 

Source
pub enum BridgeError {
    SignatureError(String),
    HttpError(Error),
    MerchantError(String),
    CryptoError(String),
    InvalidMerchantUrl(String),
    InvalidConsumerId(String),
    ReplayAttack,
    RequestTooOld(SystemTime),
    RateLimitExceeded,
    CircuitOpen,
}
Expand description

Errors that can occur in the TAP-MCP bridge.

All variants include contextual information about what went wrong. The error messages are designed to be user-facing and actionable.

§Error Recovery

This type implements #[must_use] to ensure errors are not silently ignored. Always handle errors by checking, propagating, or explicitly panicking.

Variants§

§

SignatureError(String)

TAP signature generation failed.

This error occurs when the bridge cannot generate a valid RFC 9421 HTTP Message Signature. Common causes include:

  • Invalid signing key format
  • System time errors (cannot determine signature timestamp)
  • Signature base string construction failures

§Recovery

Check that the Ed25519 signing key is valid and system time is correctly set.

§

HttpError(Error)

HTTP request failed.

This error wraps reqwest::Error and occurs when network communication with the merchant fails. Common causes include:

  • Network timeouts (default: 30 seconds)
  • Connection refused (merchant server down)
  • DNS resolution failures
  • TLS/SSL errors

§Recovery

Retry the request with exponential backoff. If the error persists, verify:

  • Merchant URL is correct and accessible
  • Network connectivity is available
  • Firewall/proxy settings allow HTTPS connections
§

MerchantError(String)

Invalid merchant response.

This error occurs when the merchant returns a response that violates the TAP protocol. Common causes include:

  • Unexpected HTTP status code
  • Malformed JSON response
  • Missing required fields in response
  • Protocol version mismatch

§Recovery

This usually indicates a merchant-side issue. Contact the merchant to verify:

  • Their TAP implementation is up to date
  • The endpoint accepts the request format being sent
  • Any API keys or authentication tokens are valid
§

CryptoError(String)

Cryptographic operation failed.

This error occurs when a low-level cryptographic operation fails. Common causes include:

  • Invalid key material
  • Hash computation failures
  • Base64 encoding/decoding errors

§Recovery

Verify that:

  • Signing keys are valid Ed25519 keys
  • Key material has not been corrupted
  • System has sufficient entropy for cryptographic operations
§

InvalidMerchantUrl(String)

Invalid merchant URL.

This error occurs when input validation rejects a merchant URL. Common causes include:

  • Non-HTTPS URL (HTTP is not allowed)
  • Localhost or loopback addresses (security restriction)
  • Malformed URL syntax

§Recovery

Ensure the merchant URL:

  • Uses HTTPS scheme (https://)
  • Is not a localhost address (localhost, 127.0.0.1)
  • Has valid syntax per RFC 3986

§Examples

use tap_mcp_bridge::error::BridgeError;

// These URLs will be rejected:
let err = BridgeError::InvalidMerchantUrl("http://example.com".to_string());
assert!(err.to_string().contains("Invalid merchant URL"));

let err = BridgeError::InvalidMerchantUrl("https://localhost/checkout".to_string());
assert!(err.to_string().contains("Invalid merchant URL"));
§

InvalidConsumerId(String)

Invalid consumer ID.

This error occurs when input validation rejects a consumer ID. Consumer IDs must meet these requirements:

  • Not empty
  • Maximum 64 characters
  • Only alphanumeric characters, hyphens, and underscores

§Recovery

Ensure the consumer ID:

  • Contains only letters (a-z, A-Z), numbers (0-9), hyphens (-), and underscores (_)
  • Has at least 1 character
  • Has no more than 64 characters

§Examples

use tap_mcp_bridge::error::BridgeError;

// These consumer IDs will be rejected:
let err = BridgeError::InvalidConsumerId("consumer@example.com".to_string());
assert!(err.to_string().contains("Invalid consumer ID"));

let err = BridgeError::InvalidConsumerId("".to_string());
assert!(err.to_string().contains("Invalid consumer ID"));
§

ReplayAttack

Replay attack detected.

This error occurs when a request with a previously seen nonce is received within the 8-minute validity window.

§

RequestTooOld(SystemTime)

Request too old.

This error occurs when the request timestamp is outside the allowed window.

§

RateLimitExceeded

Rate limit exceeded.

This error occurs when too many requests are made in a short period. Rate limiting protects against DoS attacks and ensures fair resource usage.

§Recovery

Wait a short period (e.g., 1 second) and retry the request. Consider implementing exponential backoff for repeated failures.

§

CircuitOpen

Circuit breaker is open.

This error occurs when the circuit breaker has detected too many failures and is temporarily rejecting all requests to prevent cascading failures. The circuit will automatically transition to half-open state after the reset timeout expires.

§Recovery

Wait for the circuit breaker’s reset timeout to expire (typically 60 seconds). The circuit will then allow limited test requests to determine if the underlying service has recovered.

Trait Implementations§

Source§

impl Debug for BridgeError

Source§

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

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

impl Display for BridgeError

Source§

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

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

impl Error for BridgeError

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<Error> for BridgeError

Source§

fn from(source: Error) -> 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> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
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> ToStringFallible for T
where T: Display,

Source§

fn try_to_string(&self) -> Result<String, TryReserveError>

ToString::to_string, but without panic on OOM.

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