class Gapic::Rest::Error

Gapic REST exception class

Attributes

details[R]

@return [Object, nil] the details as parsed from the response body

header[R]

@return [Object, nil] the headers of the REST error

headers[R]

@return [Object, nil] the headers of the REST error

status[R]

@return [Object, nil] the text representation of status as parsed from the response body

status_code[R]

@return [Integer, nil] the http status code for the error

Public Class Methods

new(message, status_code, status: nil, details: nil, headers: nil) click to toggle source

@param message [String, nil] error message @param status_code [Integer, nil] HTTP status code of this error @param status [String, nil] The text representation of status as parsed from the response body @param details [Object, nil] Details data of this error @param headers [Object, nil] Http headers data of this error

Calls superclass method
# File lib/gapic/rest/error.rb, line 40
def initialize message, status_code, status: nil, details: nil, headers: nil
  super message
  @status_code = status_code
  @status = status
  @details = details
  @headers = headers
end
wrap_faraday_error(err) click to toggle source

This creates a new error message wrapping the Faraday's one. Additionally it tries to parse and set a detailed message and an error code from from the Google Cloud's response body

@param err [Faraday::Error] the Faraday error to wrap

@return [ Gapic::Rest::Error]

# File lib/gapic/rest/error.rb, line 57
def wrap_faraday_error err
  message = err.message
  status_code = err.response_status
  status = nil
  details = nil
  headers = err.response_headers

  if err.response_body
    msg, code, status, details = try_parse_from_body err.response_body
    message = "An error has occurred when making a REST request: #{msg}" unless msg.nil?
    status_code = code unless code.nil?
  end

  Gapic::Rest::Error.new message, status_code, status: status, details: details, headers: headers
end

Private Class Methods

parse_details(details) click to toggle source

@private Parses the details data, trying to extract the Protobuf.Any objects from it, if it's an array of hashes. Otherwise returns it as is.

@param details [Object, nil] the details object

@return [Object, nil]

# File lib/gapic/rest/error.rb, line 108
def parse_details details
  # For rest errors details will contain json representations of `Protobuf.Any`
  # decoded into hashes. If it's not an array, of its elements are not hashes,
  # it's some other case
  return details unless details.is_a? ::Array

  details.map do |detail_instance|
    next detail_instance unless detail_instance.is_a? ::Hash
    # Next, parse detail_instance into a Proto message.
    # There are three possible issues for the JSON->Any->message parsing
    # - json decoding fails
    # - the json belongs to a proto message type we don't know about
    # - any unpacking fails
    # If we hit any of these three issues we'll just return the original hash
    begin
      any = ::Google::Protobuf::Any.decode_json detail_instance.to_json
      klass = ::Google::Protobuf::DescriptorPool.generated_pool.lookup(any.type_name)&.msgclass
      next detail_instance if klass.nil?
      unpack = any.unpack klass
      next detail_instance if unpack.nil?
      unpack
    rescue ::Google::Protobuf::ParseError
      detail_instance
    end
  end.compact
end
try_parse_from_body(body_str) click to toggle source

@private Tries to get the error information from the JSON bodies

@param body_str [String] @return [Array(String, String, String, String)]

# File lib/gapic/rest/error.rb, line 81
def try_parse_from_body body_str
  body = JSON.parse body_str

  unless body.is_a?(::Hash) && body&.key?("error") && body["error"].is_a?(::Hash)
    return [nil, nil, nil, nil]
  end
  error = body["error"]

  message = error["message"] if error.key? "message"
  code = error["code"] if error.key? "code"
  status = error["status"] if error.key? "status"

  details = parse_details error["details"] if error.key? "details"

  [message, code, status, details]
rescue JSON::ParserError
  [nil, nil, nil, nil]
end