we-promise/sure · error · Provider::EnableBanking::EnableBankingError
request_failed
request_failed
Error message
Exception during GET request: #{e.message} What it means
Raised by Provider::EnableBanking#get_aspsps when the GET to https://api.enablebanking.com/aspsps fails at the transport layer with SocketError (DNS resolution or routing failure), Net::OpenTimeout (connect timeout), or Net::ReadTimeout (response exceeded the 120s read timeout). It is wrapped as EnableBankingError(:request_failed) with the original transport message preserved.
Source
Thrown at app/models/provider/enable_banking.rb:36
def initialize(application_id:, client_certificate:)
@application_id = application_id
@private_key = extract_private_key(client_certificate)
end
# Get list of available ASPSPs (banks) for a country
# @param country [String] ISO 3166-1 alpha-2 country code (e.g., "GB", "DE", "FR")
# @return [Array<Hash>] List of ASPSPs
def get_aspsps(country:)
response = self.class.get(
"#{BASE_URL}/aspsps",
headers: auth_headers,
query: { country: country }
)
handle_response(response)
rescue SocketError, Net::OpenTimeout, Net::ReadTimeout => e
raise EnableBankingError.new("Exception during GET request: #{e.message}", :request_failed)
end
# Initiate authorization flow - returns a redirect URL for the user
# @param aspsp_name [String] Name of the ASPSP from get_aspsps
# @param aspsp_country [String] Country code for the ASPSP
# @param redirect_url [String] URL to redirect user back to after auth
# @param state [String, nil] State parameter to pass through
# @param psu_type [String] "personal" or "business"
# @param maximum_consent_validity [Integer, nil] Max consent duration in seconds from ASPSP (nil = use 90 days)
# @param language [String, nil] Two-letter language code (e.g. "fr", "en")
# @param auth_method [String, nil] Name of a specific authentication method to use (from the ASPSP's
# auth_methods list). Required to drive DECOUPLED/EMBEDDED banks that expose several methods; when nil
# Enable Banking falls back to the ASPSP's default method.
# @return [Hash] Contains :url and :authorization_id
def start_authorization(aspsp_name:, aspsp_country:, redirect_url:, state: nil,
psu_type: "personal", maximum_consent_validity: nil, language: nil, auth_method: nil)
max_seconds = maximum_consent_validity ? [ maximum_consent_validity, 1 ].max : 90.days.to_i
valid_until = [ Time.current + max_seconds.seconds, Time.current + 90.days ].minView on GitHub (pinned to e69894adb9)
Solutions
- Verify reachability from the same environment: curl -v 'https://api.enablebanking.com/aspsps?country=FI'
- If DNS fails, fix resolver/VPN; if connect times out, allow egress to api.enablebanking.com:443
- Retry with backoff — this endpoint is a plain read, safe to retry
- If ReadTimeout recurs, check Enable Banking status before raising the client timeout above 120s
Example fix
# before banks = client.get_aspsps(country: "DE") # after attempts = 0 begin banks = client.get_aspsps(country: "DE") rescue Provider::EnableBanking::EnableBankingError => e raise unless e.error_type == :request_failed && (attempts += 1) <= 3 sleep(2**attempts) retry end
Defensive patterns
Strategy: retry
Validate before calling
require "socket"
def enable_banking_reachable?
Socket.tcp("api.enablebanking.com", 443, connect_timeout: 5).close
true
rescue SocketError, Errno::ETIMEDOUT, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
false
end Type guard
def eb_request_failed?(error) error.is_a?(Provider::EnableBanking::EnableBankingError) && error.error_type == :request_failed end
Try / catch
attempts = 0 begin banks = client.get_aspsps(country: "DE") rescue Provider::EnableBanking::EnableBankingError => e raise unless e.error_type == :request_failed && (attempts += 1) <= 3 sleep(2**attempts) retry end
Prevention
- Probe api.enablebanking.com:443 reachability at worker boot in restricted environments
- Cache the ASPSP list briefly — it changes rarely and reduces calls
- Validate country format client-side before spending a network call
- Distinguish :request_failed (transport) from API-status errors before choosing retry vs reauth
When it happens
Trigger: Calling get_aspsps(country: "XX") in an environment where api.enablebanking.com cannot be resolved (SocketError), outbound 443 is blocked by firewall/container policy (OpenTimeout), or the endpoint hangs past the 120s HTTParty timeout (ReadTimeout).
Common situations: Local development without internet or with a VPN that blocks the host, CI containers with restricted egress, DNS outages, transient upstream slowness.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/aa8c8a9bca812151.
Report an issue: GitHub.