{"record":{"id":"fa0319c4ae0daca6","repo":"arsduo/koala","slug":"koala-facebook-servererror-new-result-status-to","errorCode":null,"errorMessage":"Koala::Facebook::ServerError.new(result.status.to_i, result.body)","messagePattern":"Koala::Facebook::ServerError\\.new\\(result\\.status\\.to_i, result\\.body\\)","errorType":"exception","errorClass":"Koala::Facebook::ServerError","httpStatus":500,"severity":"error","filePath":"lib/koala/api.rb","lineNumber":125,"sourceCode":"        # This is explicitly needed in batch requests so GraphCollection\n        # results preserve any specific access tokens provided\n        args[\"access_token\"] ||= @access_token || @app_access_token if @access_token || @app_access_token\n\n        if options.delete(:appsecret_proof) && args[\"access_token\"] && @app_secret\n          args[\"appsecret_proof\"] = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new(\"sha256\"), @app_secret, args[\"access_token\"])\n        end\n\n        # Translate any arrays in the params into comma-separated strings\n        args = sanitize_request_parameters(args) unless preserve_form_arguments?(options)\n\n        # add a leading / if needed...\n        path = \"/#{path}\" unless path.to_s =~ /^\\//\n\n        # make the request via the provided service\n        result = Koala.make_request(path, args, verb, options)\n\n        if result.status.to_i >= 500\n          raise Koala::Facebook::ServerError.new(result.status.to_i, result.body)\n        end\n\n        result\n      end\n\n      private\n\n      # Sanitizes Ruby objects into Facebook-compatible string values.\n      #\n      # @param parameters a hash of parameters.\n      #\n      # Returns a hash in which values that are arrays of non-enumerable values\n      #         (Strings, Symbols, Numbers, etc.) are turned into comma-separated strings.\n      def sanitize_request_parameters(parameters)\n        parameters.reduce({}) do |result, (key, value)|\n          # if the parameter is an array that contains non-enumerable values,\n          # turn it into a comma-separated list\n          # in Ruby 1.8.7, strings are enumerable, but we don't care","sourceCodeStart":107,"sourceCodeEnd":143,"githubUrl":"https://github.com/arsduo/koala/blob/47d052063ef8b5644fb59e279da0b52687999f55/lib/koala/api.rb#L107-L143","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"# before: any 5xx from Facebook kills the job\nresult = @api.get_object('me')\n\n# after: bounded retry with exponential backoff\ndef graph_with_retry(api, max_attempts = 3)\n  attempts = 0\n  begin\n    attempts += 1\n    yield\n  rescue Koala::Facebook::ServerError => e\n    raise if attempts >= max_attempts\n    sleep(2**attempts) # 2s, then 4s\n    retry\n  end\nend\n\nresult = graph_with_retry(@api) { @api.get_object('me') }","handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":"attempts = 0\nbegin\n  attempts += 1\n  api.get_object('me')\nrescue Koala::Facebook::ServerError => e\n  raise if attempts >= 3   # bounded: 5xx is usually transient, not forever\n  sleep(2**attempts)       # exponential backoff: 2s, 4s\n  retry\nend\n# rescue ServerError before APIError when branching on 5xx vs 4xx — ServerError is the 5xx subclass","preventionTips":["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"],"tags":["http-5xx","facebook-graph-api","transient","retryable","server-error"],"backgroundTag":"http-5xx-server-error","analyzedSha":"47d052063ef8b5644fb59e279da0b52687999f55","analyzedAt":"2026-08-23T10:19:03.891Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}