Merge branch 'master' of https://github.com/google/google-api-ruby-client
This commit is contained in:
		
						commit
						b8f6f7c2fe
					
				| 
						 | 
				
			
			@ -52,6 +52,9 @@ module Google
 | 
			
		|||
        #
 | 
			
		||||
        # @return [void]
 | 
			
		||||
        def prepare!
 | 
			
		||||
          if options && options.api_format_version
 | 
			
		||||
            header['X-Goog-Api-Format-Version'] = options.api_format_version.to_s
 | 
			
		||||
          end
 | 
			
		||||
          query[FIELDS_PARAM] = normalize_fields_param(query[FIELDS_PARAM]) if query.key?(FIELDS_PARAM)
 | 
			
		||||
          if request_representation && request_object
 | 
			
		||||
            header['Content-Type'] ||= JSON_CONTENT_TYPE
 | 
			
		||||
| 
						 | 
				
			
			@ -100,15 +103,15 @@ module Google
 | 
			
		|||
        def check_status(status, header = nil, body = nil, message = nil)
 | 
			
		||||
          case status
 | 
			
		||||
          when 400, 402...500
 | 
			
		||||
            error = parse_error(body)
 | 
			
		||||
            if error
 | 
			
		||||
              message = sprintf('%s: %s', error['reason'], error['message'])
 | 
			
		||||
              raise ERROR_REASON_MAPPING[error['reason']].new(
 | 
			
		||||
            reason, message = parse_error(body)
 | 
			
		||||
            if reason
 | 
			
		||||
              message = sprintf('%s: %s', reason, message)
 | 
			
		||||
              raise ERROR_REASON_MAPPING[reason].new(
 | 
			
		||||
                message,
 | 
			
		||||
                status_code: status,
 | 
			
		||||
                header: header,
 | 
			
		||||
                body: body
 | 
			
		||||
              ) if ERROR_REASON_MAPPING.key?(error['reason'])
 | 
			
		||||
              ) if ERROR_REASON_MAPPING.key?(reason)
 | 
			
		||||
            end
 | 
			
		||||
            super(status, header, body, message)
 | 
			
		||||
          else
 | 
			
		||||
| 
						 | 
				
			
			@ -122,15 +125,45 @@ module Google
 | 
			
		|||
 | 
			
		||||
        private
 | 
			
		||||
 | 
			
		||||
        # Attempt to parse a JSON error message, returning the first found error
 | 
			
		||||
        # Attempt to parse a JSON error message
 | 
			
		||||
        # @param [String] body
 | 
			
		||||
        #  HTTP response body
 | 
			
		||||
        # @return [Hash]
 | 
			
		||||
        # @return [Array<(String, String)>]
 | 
			
		||||
        #   Error reason and message
 | 
			
		||||
        def parse_error(body)
 | 
			
		||||
          hash = JSON.load(body)
 | 
			
		||||
          hash['error']['errors'].first
 | 
			
		||||
          obj = JSON.load(body)
 | 
			
		||||
          error = obj['error']
 | 
			
		||||
          if error['details']
 | 
			
		||||
            return extract_v2_error_details(error)
 | 
			
		||||
          elsif error['errors']
 | 
			
		||||
            return extract_v1_error_details(error)
 | 
			
		||||
          else
 | 
			
		||||
            fail 'Can not parse error message. No "details" or "errors" detected'
 | 
			
		||||
          end
 | 
			
		||||
        rescue
 | 
			
		||||
          nil
 | 
			
		||||
          return [nil, nil]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Extracts details from a v1 error message
 | 
			
		||||
        # @param [Hash] error
 | 
			
		||||
        #  Parsed JSON
 | 
			
		||||
        # @return [Array<(String, String)>]
 | 
			
		||||
        #   Error reason and message
 | 
			
		||||
        def extract_v1_error_details(error)
 | 
			
		||||
          reason = error['errors'].first['reason']
 | 
			
		||||
          message = error['message']
 | 
			
		||||
          return [reason, message]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Extracts details from a v2error message
 | 
			
		||||
        # @param [Hash] error
 | 
			
		||||
        #  Parsed JSON
 | 
			
		||||
        # @return [Array<(String, String)>]
 | 
			
		||||
        #   Error reason and message
 | 
			
		||||
        def extract_v2_error_details(error)
 | 
			
		||||
          reason = error['status']
 | 
			
		||||
          message = error['message']
 | 
			
		||||
          return [reason, message]
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        # Convert field names from ruby conventions to original names in JSON
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ module Google
 | 
			
		|||
          end
 | 
			
		||||
        end
 | 
			
		||||
 | 
			
		||||
        def to_json
 | 
			
		||||
        def to_json(*a)
 | 
			
		||||
          representation = self.class.const_get(:Representation)
 | 
			
		||||
          representation.new(self).to_json(user_options: { skip_undefined: true })
 | 
			
		||||
        end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,7 +30,8 @@ module Google
 | 
			
		|||
      :header,
 | 
			
		||||
      :normalize_unicode,
 | 
			
		||||
      :skip_serialization,
 | 
			
		||||
      :skip_deserialization)
 | 
			
		||||
      :skip_deserialization,
 | 
			
		||||
      :api_format_version)
 | 
			
		||||
 | 
			
		||||
    # General client options
 | 
			
		||||
    class ClientOptions
 | 
			
		||||
| 
						 | 
				
			
			@ -67,6 +68,8 @@ module Google
 | 
			
		|||
      #   @return [Boolean] True if body object should be treated as raw text instead of an object.
 | 
			
		||||
      # @!attribute [rw] skip_deserialization
 | 
			
		||||
      #   @return [Boolean] True if response should be returned in raw form instead of deserialized.
 | 
			
		||||
      # @!attribute [rw] api_format_version
 | 
			
		||||
      #   @return [Fixnum] Version of the error format to request/expect.
 | 
			
		||||
 | 
			
		||||
      # Get the default options
 | 
			
		||||
      # @return [Google::Apis::RequestOptions]
 | 
			
		||||
| 
						 | 
				
			
			@ -85,7 +88,7 @@ module Google
 | 
			
		|||
        new_options
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    ClientOptions.default.log_http_requests = false
 | 
			
		||||
    ClientOptions.default.application_name = 'unknown'
 | 
			
		||||
    ClientOptions.default.application_version = '0.0.0'
 | 
			
		||||
| 
						 | 
				
			
			@ -93,5 +96,6 @@ module Google
 | 
			
		|||
    RequestOptions.default.normalize_unicode = false
 | 
			
		||||
    RequestOptions.default.skip_serialization = false
 | 
			
		||||
    RequestOptions.default.skip_deserialization = false
 | 
			
		||||
    RequestOptions.default.api_format_version = nil
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -280,4 +280,52 @@ EOF
 | 
			
		|||
      expect { command.execute(client) }.to raise_error(/Invalid request/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  context('with v2 error messages') do
 | 
			
		||||
    let(:command) do
 | 
			
		||||
      cmd = Google::Apis::Core::ApiCommand.new(:get, 'https://www.googleapis.com/zoo/animals')
 | 
			
		||||
      cmd.options.api_format_version = 2
 | 
			
		||||
      cmd
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    before(:example) do
 | 
			
		||||
      json = <<EOF
 | 
			
		||||
{
 | 
			
		||||
  "error": {
 | 
			
		||||
    "code": 400,
 | 
			
		||||
    "message": "Illegal character ':' in log name",
 | 
			
		||||
    "status": "INVALID_ARGUMENT",
 | 
			
		||||
    "details": [
 | 
			
		||||
      {
 | 
			
		||||
        "@type": "type.googleapis.com/google.logging.v2.WriteLogEntriesPartialErrors",
 | 
			
		||||
        "logEntryErrors": {
 | 
			
		||||
          "0": {
 | 
			
		||||
            "code": 3,
 | 
			
		||||
            "message": "Illegal character ':' in log name"
 | 
			
		||||
          },
 | 
			
		||||
          "1": {
 | 
			
		||||
            "code": 7,
 | 
			
		||||
            "message": "User not authorized."
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    ]
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
      stub_request(:get, 'https://www.googleapis.com/zoo/animals')
 | 
			
		||||
        .with(headers: {'X-Goog-Api-Format-Version' => '2'})
 | 
			
		||||
        .to_return(status: [400, 'Invalid Argument'], headers: { 'Content-Type' => 'application/json' }, body: json)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'should raise client error' do
 | 
			
		||||
      expect { command.execute(client) }.to raise_error(Google::Apis::ClientError)
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    it 'should raise an error with the reason and message' do
 | 
			
		||||
      expect { command.execute(client) }.to raise_error(
 | 
			
		||||
        /INVALID_ARGUMENT: Illegal character ':' in log name/)
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue