we-promise/sure · error · EnableBankingError

parse_error

parse_error

Error message

Failed to parse API response

What it means

Raised by parse_response_body when a 2xx response body exists but is not valid JSON. Blank bodies are fine; anything else - an HTML WAF/challenge page, a truncated body, a BOM-prefixed payload - raises JSON::ParserError, which is logged and re-raised as EnableBankingError(:parse_error). Note the asymmetry: error responses use the lenient parse_error_response_body (raw_body fallback), success responses use this strict one.

Source

Thrown at app/models/provider/enable_banking.rb:319

        raise EnableBankingError.new("Failed to fetch data: #{response.code} #{response.message} - #{response.body}", :fetch_failed, response_data: response_data)
      end
    end

    def parse_error_response_body(response)
      return {} if response.body.blank?

      JSON.parse(response.body, symbolize_names: true)
    rescue JSON::ParserError
      { raw_body: response.body.to_s }
    end

    def parse_response_body(response)
      return {} if response.body.blank?

      JSON.parse(response.body, symbolize_names: true)
    rescue JSON::ParserError => e
      Rails.logger.error "Enable Banking API: Failed to parse response: #{e.message}"
      raise EnableBankingError.new("Failed to parse API response", :parse_error)
    end

    class EnableBankingError < StandardError
      attr_reader :error_type, :response_data

      def initialize(message, error_type = :unknown, response_data: nil)
        super(message)
        @error_type = error_type
        @response_data = response_data
      end

      def wrong_transactions_period?
        error_type == :validation_error && response_data.is_a?(Hash) && response_data[:error] == "WRONG_TRANSACTIONS_PERIOD"
      end

      def corrected_date_from
        value = response_data&.dig(:detail, :date_from)

View on GitHub (pinned to e69894adb9)

Solutions

  1. Check the preceding Rails log line 'Enable Banking API: Failed to parse response:' for the JSON::ParserError detail (unexpected token at...) - HTML bodies are obvious there
  2. Retry once after a short delay: interstitials and truncation are usually transient
  3. Strip a UTF-8 BOM before parsing and capture the raw body in the error/DebugLogEntry so the payload is diagnosable
  4. If persistent, verify nothing between the app and the API rewrites responses (proxy, SSL inspection)

Example fix

# app/models/provider/enable_banking.rb - parse_response_body
# before
JSON.parse(response.body, symbolize_names: true)

# after
body = response.body.to_s.delete_prefix("\xEF\xBB\xBF")
JSON.parse(body, symbolize_names: true)
Defensive patterns

Strategy: try-catch

Type guard

def enable_banking_parse_error?(error)
  error.is_a?(Provider::EnableBanking::EnableBankingError) && error.error_type == :parse_error
end

Try / catch

begin
  provider.get_session(session_id: sid)
rescue Provider::EnableBanking::EnableBankingError => e
  raise unless e.error_type == :parse_error
  raise if e.message.include?("<html") # WAF page - retry once, then give up
  retry # transient truncation
end

Prevention

When it happens

Trigger: An edge proxy/CDN in front of api.enablebanking.com returns a 200 HTML interstitial; the connection drops mid-body leaving truncated JSON; the payload starts with a UTF-8 BOM so JSON.parse rejects it; a middleware maintenance page returned with status 200.

Common situations: Cloudflare-style bot challenges hitting server-to-server traffic, flaky NAT dropping long transaction payloads, a misconfigured corporate proxy injecting an HTML banner, BOM added by a response-transforming middleware.

Understand the failure class

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/84609373ec6701dd. Report an issue: GitHub.