arsduo/koala · error · Koala::Facebook::ServerError
Koala::Facebook::ServerError.new(result.status.to_i, result.
Error message
Koala::Facebook::ServerError.new(result.status.to_i, result.body)
What it means
Koala::Facebook::ServerError is raised by Koala::Facebook::API#api whenever the underlying HTTP response from Facebook has a status of 500 or higher (lib/koala/api.rb:124-126). Koala splits Facebook failures in two: 4xx responses are parsed into ClientError/APIError carrying Facebook's structured error payload, while 5xx responses mean Facebook itself failed to process the request. The exception inherits http_status and response_body from APIError (lib/koala/errors.rb), so you can log exactly what came back. It is usually transient or Facebook-side, not a formatting bug in your call.
Source
Thrown at lib/koala/api.rb:125
# This is explicitly needed in batch requests so GraphCollection
# results preserve any specific access tokens provided
args["access_token"] ||= @access_token || @app_access_token if @access_token || @app_access_token
if options.delete(:appsecret_proof) && args["access_token"] && @app_secret
args["appsecret_proof"] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new("sha256"), @app_secret, args["access_token"])
end
# Translate any arrays in the params into comma-separated strings
args = sanitize_request_parameters(args) unless preserve_form_arguments?(options)
# add a leading / if needed...
path = "/#{path}" unless path.to_s =~ /^\//
# make the request via the provided service
result = Koala.make_request(path, args, verb, options)
if result.status.to_i >= 500
raise Koala::Facebook::ServerError.new(result.status.to_i, result.body)
end
result
end
private
# Sanitizes Ruby objects into Facebook-compatible string values.
#
# @param parameters a hash of parameters.
#
# Returns a hash in which values that are arrays of non-enumerable values
# (Strings, Symbols, Numbers, etc.) are turned into comma-separated strings.
def sanitize_request_parameters(parameters)
parameters.reduce({}) do |result, (key, value)|
# if the parameter is an array that contains non-enumerable values,
# turn it into a comma-separated list
# in Ruby 1.8.7, strings are enumerable, but we don't careView on GitHub (pinned to 47d052063e)
Solutions
- Retry with exponential backoff — 5xx responses are usually transient; wrap Koala calls in 2-3 retries or configure faraday-retry on Koala's HTTP service
- Log e.http_status, e.response_body and e.fb_error_trace_id, then check Facebook platform status and your Meta app dashboard before changing code
- If one specific call consistently 5xxes, simplify it (smaller batch, fewer nested fields, a supported Graph API version) — some payloads crash Facebook rather than produce a 4xx
- Alert on the ServerError-to-success ratio so Facebook-side incidents are distinguishable from your own regressions
Example fix
# before: any 5xx from Facebook kills the job
result = @api.get_object('me')
# after: bounded retry with exponential backoff
def graph_with_retry(api, max_attempts = 3)
attempts = 0
begin
attempts += 1
yield
rescue Koala::Facebook::ServerError => e
raise if attempts >= max_attempts
sleep(2**attempts) # 2s, then 4s
retry
end
end
result = graph_with_retry(@api) { @api.get_object('me') } Defensive patterns
Strategy: retry
Try / catch
attempts = 0
begin
attempts += 1
api.get_object('me')
rescue Koala::Facebook::ServerError => e
raise if attempts >= 3 # bounded: 5xx is usually transient, not forever
sleep(2**attempts) # exponential backoff: 2s, 4s
retry
end
# rescue ServerError before APIError when branching on 5xx vs 4xx — ServerError is the 5xx subclass Prevention
- Wrap Koala calls in bounded exponential-backoff retry (2-3 attempts) — 5xx responses are usually transient
- Configure faraday-retry on the Faraday connection used by Koala.http_service to centralize retries instead of per-call begin/rescue
- Make write jobs idempotent so a retry after a 5xx never duplicates a post
- Log e.http_status and e.response_body with every ServerError for incident review
- Check Facebook platform status before debugging client code when these errors spike
When it happens
Trigger: Any request routed through #api — get_object, get_connections, put_connections, delete_object, search, graph_call, batch operations, FQL/REST calls — that Facebook answers with HTTP 500/502/503/504. Example: a background job calling @api.get_object('me') during a Facebook outage, or a large batch whose operations trip a server-side crash.
Common situations: Scheduled jobs with no retry logic dying on the first transient 500; Facebook platform incidents and deploy windows; occasional edge-case payloads that make Graph API crash server-side instead of returning a 4xx; Graph API version migrations where a deprecated call starts 500ing.
Related errors
- ServerError.new(response.status, response.body)
- Batch operations require an access token, none provided.
- Delete requires an access token
- Write operations require an access token
- Unliking requires an access token
AI-assisted analysis of arsduo/koala@47d052063e (2026-08-23).
Data as JSON: /api/errors/fa0319c4ae0daca6.
Report an issue: GitHub.