we-promise/sure · error · Provider::Simplefin::SimplefinError
fetch_failed
fetch_failed
Error message
Failed to fetch accounts: #{response.code} #{response.message} - #{response.body} What it means
Raised by Provider::Simplefin's response handler for any HTTP status not explicitly handled (everything other than 200, 400, 402, 403, 429, 500-599). It is the catch-all 'unexpected response' branch of the accounts fetch; the message embeds the raw status code, HTTP message, and body so the actual status can be diagnosed. The error_type is :fetch_failed.
Source
Thrown at app/models/provider/simplefin.rb:103
case response.code
when 200
JSON.parse(response.body, symbolize_names: true)
when 400
Rails.logger.error "SimpleFin API: Bad request - #{response.body}"
raise SimplefinError.new("Bad request to SimpleFin API: #{response.body}", :bad_request)
when 403
raise SimplefinError.new("Access URL is no longer valid", :access_forbidden)
when 402
raise SimplefinError.new("Payment required to access this account", :payment_required)
when 429
Rails.logger.warn "SimpleFin API: Rate limited - #{response.body}"
raise SimplefinError.new("SimpleFin rate limit exceeded. Please try again later.", :rate_limited)
when 500..599
Rails.logger.error "SimpleFin API: Server error - Code: #{response.code}, Body: #{response.body}"
raise SimplefinError.new("SimpleFin server error (#{response.code}). Please try again later.", :server_error)
else
Rails.logger.error "SimpleFin API: Unexpected response - Code: #{response.code}, Body: #{response.body}"
raise SimplefinError.new("Failed to fetch accounts: #{response.code} #{response.message} - #{response.body}", :fetch_failed)
end
end
def get_info(base_url)
# Use self.class.get to inherit class-level SSL and timeout defaults
response = self.class.get("#{base_url}/info")
case response.code
when 200
response.body.strip.split("\n")
else
raise SimplefinError.new("Failed to get server info: #{response.code} #{response.message}", :info_failed)
end
end
class SimplefinError < StandardError
attr_reader :error_type
View on GitHub (pinned to e69894adb9)
Solutions
- Read the code in the message: 301/302 means the access URL moved - re-generate/re-link the access URL in SimpleFIN and update the stored credential
- Verify the stored access URL with an exact curl reproduction of the request
- Check the Rails log line 'SimpleFin API: Unexpected response - Code: ... Body: ...' for the body, which often names the real problem
- If SimpleFIN changed its endpoint shape, update this case statement to handle the new status explicitly
Defensive patterns
Strategy: try-catch
Try / catch
begin simplefin.get_accounts rescue Provider::Simplefin::SimplefinError => e case e.error_type when :fetch_failed then flag_access_url_for_relink(e.message) # unexpected status: usually stale URL else raise end end
Prevention
- Validate the stored access URL format (https, host present) before first use
- Treat any redirect-bearing status as 'relink needed' rather than a code bug
- Log error_type alongside the message so unhandled statuses are countable
When it happens
Trigger: The access URL returns an unhandled status: 301/302 redirect (HTTParty does not follow redirects by default, so a moved/rotated access URL lands here), 401, 404, 405, or 410. Any surprising non-listed code from the SimpleFIN endpoint hits this branch.
Common situations: SimpleFIN rotated or invalidated the access URL and now redirects; the stored access URL was truncated or copy-pasted wrongly; the endpoint scheme changed after a SimpleFIN product update; a 404 from a malformed URL.
Related errors
- access_forbidden
- server_error
- Please provide a name and a complete US address (street, cit
- fetch_failed
- token_compromised
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/220b0f260ffe42e5.
Report an issue: GitHub.