Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions lib/gitlab/error.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ class Parsing < Error; end

# Custom error class for rescuing from HTTP response errors.
class ResponseError < Error
POSSIBLE_MESSAGE_KEYS = %i(message error_description error)

def initialize(response)
@response = response
super(build_error_message)
Expand All @@ -37,14 +39,19 @@ def response_message
# @return [String]
def build_error_message
parsed_response = @response.parsed_response
message = parsed_response.respond_to?(:message) ? parsed_response.message : parsed_response['message']
message = parsed_response.respond_to?(:error) ? parsed_response.error : parsed_response['error'] unless message

message = check_error_keys(parsed_response)
"Server responded with code #{@response.code}, message: " \
"#{handle_message(message)}. " \
"Request URI: #{@response.request.base_uri}#{@response.request.path}"
end

# Error keys vary across the API, find the first key that the parsed_response
# object responds to and return that, otherwise return the original.
def check_error_keys(resp)
key = POSSIBLE_MESSAGE_KEYS.find { |k| resp.respond_to?(k) }
key ? resp.send(key) : resp
end

# Handle error response message in case of nested hashes
def handle_message(message)
case message
Expand Down
85 changes: 22 additions & 63 deletions spec/gitlab/error_spec.rb
Original file line number Diff line number Diff line change
@@ -1,72 +1,31 @@
require "spec_helper"
require "stringio"

describe Gitlab::Error do
let(:request_object) { HTTParty::Request.new(Net::HTTP::Get, '/') }
let(:response_object) { Net::HTTPOK.new('1.1', 200, 'OK') }
let(:body) { StringIO.new("{foo:'bar'}") }
let(:parsed_response) { -> { body } }

let(:response) do
HTTParty::Response.new(
request_object,
response_object,
parsed_response,
body: body
)
end

let(:error) { Gitlab::Error::ResponseError.new(response) }
let(:date) { Date.new(2010, 1, 15).to_s }
require 'spec_helper'

describe Gitlab::Error::ResponseError do
before do
def body.message
string
end

response_object['last-modified'] = date
response_object['content-length'] = "1024"
@request_double = double(base_uri: 'https://gitlab.com/api/v3', path: '/foo')
end

describe "#handle_message" do
let(:array) { Array.new(['First message.', 'Second message.']) }
let(:obj_h) do
Gitlab::ObjectifiedHash.new(
user: ['not set'],
password: ['too short'],
embed_entity: { foo: ['bar'], sna: ['fu'] }
)
end

context "when passed an ObjectifiedHash" do
it "returns a joined string of error messages sorted by key" do
expect(error.send(:handle_message, obj_h)).
to eq(
"'embed_entity' (foo: bar) (sna: fu), 'password' too short, 'user' not set"
)
end
end

context "when passed an Array" do
it "returns a joined string of messages" do
expect(error.send(:handle_message, array)).
to eq("First message. Second message.")
end
end

context "when passed a String" do
it "returns the String untouched" do
error_str = 'this is an error string'

expect(error.send(:handle_message, error_str)).
to eq(error_str)
end
end
let(:expected_messages) do
[
%r{Server responded with code \d+, message: Displayed message. Request URI: https://gitlab.com/api/v3/foo},
%r{Server responded with code \d+, message: Displayed error_description. Request URI: https://gitlab.com/api/v3/foo},
%r{Server responded with code \d+, message: Displayed error. Request URI: https://gitlab.com/api/v3/foo},
%r{Server responded with code \d+, message: 'embed_entity' \(foo: bar\) \(sna: fu\), 'password' too short. Request URI: https://gitlab.com/api/v3/foo},
%r{Server responded with code \d+, message: First message. Second message.. Request URI: https://gitlab.com/api/v3/foo},
]
end

describe "#response_message" do
it "returns the message of the parsed_response" do
expect(error.response_message).to eq(body.string)
# Set up some response scenarios to test.
[
{ code: 401, parsed_response: Gitlab::ObjectifiedHash.new(message: 'Displayed message', error_description: 'should not be displayed', error: 'also will not be displayed')},
{ code: 404, parsed_response: Gitlab::ObjectifiedHash.new(error_description: 'Displayed error_description', error: 'also will not be displayed')},
{ code: 401, parsed_response: Gitlab::ObjectifiedHash.new(error: 'Displayed error')},
{ code: 500, parsed_response: Gitlab::ObjectifiedHash.new(embed_entity: { foo: ['bar'], sna: ['fu']}, password: ['too short'])},
{ code: 403, parsed_response: Array.new(['First message.', 'Second message.'])},
].each_with_index do |data, index|
it 'returns the expected message' do
response_double = double(**data, request: @request_double)
expect(described_class.new(response_double).message).to match expected_messages[index]
end
end
end