module Airbrake::Response

Parses responses coming from the Airbrake API. Handles HTTP errors by logging them.

@api private @since v1.0.0

Constants

BAD_GATEWAY

@return [Integer] HTTP code returened when the server, while acting as a

gateway or proxy, received an invalid response from the upstream server

@since v6.2.0

BAD_REQUEST

@return [Integer] HTTP code returned when the server cannot or will not

process the request due to something that is perceived to be a client
error

@since v6.2.0

CONFLICT

@return [Integer] HTTP code returned when there’s a request conflict with

the current state of the target resource

@since v6.2.0

ENHANCE_YOUR_CALM

@return [Integer] @since v6.2.0

FORBIDDEN

@return [Integer] HTTP code returned when the server understands the

request but refuses to authorize it

@since v6.2.0

GATEWAY_TIMEOUT

@return [Integer] HTTP code returened when the server, while acting as a

gateway or proxy, did not get a response in time from the upstream
server that it needed in order to complete the request

@since v6.2.0

INTERNAL_SERVER_ERROR

@return [Integer] HTTP code returned when the server encountered an

unexpected condition that prevented it from fulfilling the request

@since v6.2.0

REQUEST_TIMEOUT

@return [Integer] HTTP code returned when the server would like to shut

down this unused connection

@since v6.2.0

TOO_MANY_REQUESTS

@return [Integer] HTTP code returned when an IP sends over 10k/min notices

TRUNCATE_LIMIT

@return [Integer] the limit of the response body

UNAUTHORIZED

@return [Integer] HTTP code returned when client request has not been

completed because it lacks valid authentication credentials for the
requested resource

@since v6.2.0

Public Class Methods

parse(response) click to toggle source

Parses HTTP responses from the Airbrake API.

@param [Net::HTTPResponse] response @return [Hash{String=>String}] parsed response rubocop:disable Metrics/MethodLength, Metrics/AbcSize

# File lib/airbrake-ruby/response.rb, line 70
def self.parse(response)
  code = response.code.to_i
  body = response.body

  begin
    case code
    when 200, 204
      logger.debug("#{LOG_LABEL} #{name} (#{code}): #{body}")
      { response.msg => response.body }
    when 201
      parsed_body = JSON.parse(body)
      logger.debug("#{LOG_LABEL} #{name} (#{code}): #{parsed_body}")
      parsed_body
    when BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, ENHANCE_YOUR_CALM
      parsed_body = JSON.parse(body)
      logger.error("#{LOG_LABEL} #{parsed_body['message']}")
      parsed_body.merge('code' => code, 'error' => parsed_body['message'])
    when TOO_MANY_REQUESTS
      parsed_body = JSON.parse(body)
      msg = "#{LOG_LABEL} #{parsed_body['message']}"
      logger.error(msg)
      {
        'code' => code,
        'error' => msg,
        'rate_limit_reset' => rate_limit_reset(response),
      }
    else
      body_msg = truncated_body(body)
      logger.error("#{LOG_LABEL} unexpected code (#{code}). Body: #{body_msg}")
      { 'code' => code, 'error' => body_msg }
    end
  rescue StandardError => ex
    body_msg = truncated_body(body)
    logger.error("#{LOG_LABEL} error while parsing body (#{ex}). Body: #{body_msg}")
    { 'code' => code, 'error' => ex.inspect }
  end
end

Private Class Methods

rate_limit_reset(response) click to toggle source
# File lib/airbrake-ruby/response.rb, line 120
def self.rate_limit_reset(response)
  Time.now + response['X-RateLimit-Delay'].to_i
end
truncated_body(body) click to toggle source

rubocop:enable Metrics/MethodLength, Metrics/AbcSize

# File lib/airbrake-ruby/response.rb, line 109
def self.truncated_body(body)
  if body.nil?
    '[EMPTY_BODY]'.freeze
  elsif body.length > TRUNCATE_LIMIT
    body[0..TRUNCATE_LIMIT] << '...'
  else
    body
  end
end