# File lib/heroku/api.rb, line 77
    def request(params, &block)
      begin
        if @second_factor
          params[:headers] ||= {}
          params[:headers]['Heroku-Two-Factor-Code'] = @second_factor
          @second_factor = nil # don't use the token again
        end
        response = @connection.request(params, &block)
      rescue Excon::Errors::HTTPStatusError => error
        klass = case error.response.status
          when 401 then Heroku::API::Errors::Unauthorized
          when 402 then Heroku::API::Errors::VerificationRequired
          when 403 then Heroku::API::Errors::Forbidden
          when 404
            if error.request[:path].match /\/apps\/\/.*/
              Heroku::API::Errors::NilApp
            else
              Heroku::API::Errors::NotFound
            end
          when 408 then Heroku::API::Errors::Timeout
          when 422 then Heroku::API::Errors::RequestFailed
          when 423 then Heroku::API::Errors::Locked
          when 429 then Heroku::API::Errors::RateLimitExceeded
          when /50./ then Heroku::API::Errors::RequestFailed
          else Heroku::API::Errors::ErrorWithResponse
        end

        decompress_response!(error.response)
        reerror = klass.new(error.message, error.response)
        reerror.set_backtrace(error.backtrace)
        raise(reerror)
      end

      if response.body && !response.body.empty?
        decompress_response!(response)
        begin
          response.body = MultiJson.load(response.body)
        rescue
          if response.headers['Content-Type'] === 'application/json'
            raise
          end
          # leave non-JSON body as is
        end
      end

      # reset (non-persistent) connection
      @connection.reset

      response
    end