Skip to content

Unable to access rate-limit error headers in NylasApiError #518

@lekemula

Description

@lekemula

Is your feature request related to a problem? Please describe.
As a client of Nylas API I would like to be able to access rate limit headers (ie. Nylas-Provider-Request-Count, Retry-After, Nylas-Gmail-Quota-Usage) when such errors occur as described in this documentation.

Describe the solution you'd like
Either expose NylasApiError#response or NylasApiError#response_headers

Describe alternatives you've considered
Currently we are monkey patching the library like so:

Monkey-patch code
require 'nylas'
require 'debug'

module MonkeyPatches
  module Nylas
    module NylasApiErrorMonkeyPatch
      # added response
      attr_accessor :response

      # Initializes an error and assigns the given attributes to it.
      #
      # @param type [Hash] Error type.
      # @param message [String] Error message.
      # @param status_code [Integer] Error status code.
      # @param provider_error [Hash, nil] The error from the provider.
      # @param request_id [Hash, nil] The ID of the request.
      # @param response [Hash, nil] The full response from the Nylas API.
      def initialize(type, message, status_code, provider_error = nil, request_id = nil, response = nil) # rubocop:disable Metrics/ParameterLists
        self.response = response
        super(type, message, status_code, provider_error, request_id)
      end

      module ClassMethods
        # Parses the error response.
        #
        # @param response [Hash] Response from the Nylas API.
        # @param status_code [Integer] Error status code.
        def parse_error_response(response, status_code)
          new(
            response['type'],
            response['message'],
            status_code,
            response['provider_error'],
            nil,
            response # added response
          )
        end
      end

    module HttpClient
      # monkey patch to add `response` to the error
      def throw_error(response, status_code)
        error_obj = response[:error]

        # If `error_obj` is just a string, turn it into a hash with default keys.
        if error_obj.is_a?(String)
          error_obj = {
            type: 'NylasApiError',
            message: error_obj
          }
        end

        provider_error = error_obj.fetch(:provider_error, nil) if error_obj.is_a?(Hash)

        ::Nylas::NylasApiError.new(
          error_obj[:type],
          error_obj[:message],
          status_code,
          provider_error,
          response[:request_id],
          response # added response
        )
      end

      def parse_json_evaluate_error(http_code, response, path, content_type = nil)
        begin
          # rename `response` to `parsed_response` to distinguish between the [RestClient::Response] and [Hash]
          parsed_response = parse_response(response) if content_type == 'application/json'
        rescue Nylas::JsonParseError
          # pass [RestClient::Response] to `handle_failed_response` instead of [Hash]
          handle_failed_response(http_code, response, path)
          raise
        end

        # pass [RestClient::Response] to `handle_failed_response` instead of [Hash]
        handle_failed_response(http_code, response, path)
        parsed_response
      end
    end
  end
end

Nylas::NylasApiError.prepend(MonkeyPatches::Nylas::NylasApiErrorMonkeyPatch)
Nylas::NylasApiError.singleton_class.prepend(MonkeyPatches::Nylas::NylasApiErrorMonkeyPatch::ClassMethods)
Nylas::HttpClient.prepend(MonkeyPatches::Nylas::HttpClient)

Additional context
N/A

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions