we-promise/sure · error · Provider::Questrade::Error
unknown
unknown
Error message
Questrade unexpected response (#{response.code}) What it means
The catch-all branch of Provider::Questrade#handle_response for any status outside 200/201/400/401/403/404/429/5xx — e.g. 202/204 with an unexpected body, 3xx redirects, or unusual 4xx codes (405, 409, 410, 422). capture_response_error logs the code and first 1000 chars of the body to the /settings/debug channel before raising Error(:unknown).
Source
Thrown at app/models/provider/questrade.rb:265
case response.code
when 200, 201
JSON.parse(response.body, symbolize_names: true)
when 400
capture_response_error("bad_request", response)
raise Error.new("Questrade bad request (#{response.code})", :bad_request)
when 401
raise AuthenticationError.new("Invalid or expired Questrade credentials", :unauthorized)
when 403
raise AuthenticationError.new("Access forbidden - check your permissions", :access_forbidden)
when 404
raise Error.new("Resource not found", :not_found)
when 429
raise RetryableResponseError.new("Questrade rate limit exceeded. Please try again later.", :rate_limited)
when 500..599
raise RetryableResponseError.new("Questrade server error (#{response.code}). Please try again later.", :server_error)
else
capture_response_error("unexpected_response", response)
raise Error.new("Questrade unexpected response (#{response.code})", :unknown)
end
end
end
View on GitHub (pinned to e69894adb9)
Solutions
- Inspect the captured DebugLogEntry (provider_key 'questrade', category 'unexpected_response') for the exact status and body.
- Replay the exact URL with curl to see raw headers — especially Location on 3xx to learn where the endpoint moved.
- If a legitimate new status appears repeatedly (e.g. 422), add an explicit when branch to handle_response instead of relying on the catch-all.
- Report/upgrade if the gem-level client is out of sync with Questrade's current API surface.
Example fix
# before
result = provider.get_balances(account_id: id) # unknown 422 swallowed as :unknown
# after
begin
result = provider.get_balances(account_id: id)
rescue Provider::Questrade::Error => e
if e.error_type == :unknown
DebugLogEntry.capture(category: "questrade", level: "warn",
message: "Unhandled Questrade status", source: self.class.name,
provider_key: "questrade", metadata: { item_id: item.id })
end
raise
end Defensive patterns
Strategy: try-catch
Try / catch
begin
provider.get_balances(account_id: id)
rescue Provider::Questrade::Error => e
if e.error_type == :unknown
DebugLogEntry.capture(category: "questrade", level: "warn",
message: "unhandled status: #{e.message}", source: self.class.name, provider_key: "questrade")
end
raise
end Prevention
- Check /settings/debug for the captured status/body before guessing.
- When a new status recurs (e.g. 422), add an explicit branch to handle_response instead of living on the catch-all.
When it happens
Trigger: A 204 No Content from an endpoint where the client expects JSON (handle_response would parse empty body on 200 but a 204 lands here); a redirect because api_server responded with a moved endpoint; new 4xx semantics Questrade introduced that the case statement does not enumerate.
Common situations: Questrade API version changes adding 422 validation responses; proxies returning 502 is covered (5xx) but 502-with-3xx-redirect chains are not; endpoints returning 202 for async processing hitting synchronous client code.
Related errors
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/b51c89ca7f85cd17.
Report an issue: GitHub.