Improve handling of failed requests

This adds a custom exception class with an error type that can be more
easily used by clients. It also explicitly handles failed connections as
such.

closes #9
This commit is contained in:
Basti 2020-06-09 10:48:26 +02:00
parent c5d5c123a6
commit 4c36da46fe
No known key found for this signature in database
GPG Key ID: BE4634D632D39B67
3 changed files with 62 additions and 4 deletions

11
lib/manifique/errors.rb Normal file
View File

@ -0,0 +1,11 @@
module Manifique
class Error < ::StandardError
attr_reader :type, :url
def initialize(msg="Encountered an error", type="generic", url)
@type = type
@url = url
super(msg)
end
end
end

View File

@ -1,8 +1,9 @@
require 'json' require 'json'
require 'faraday' require 'faraday'
require 'faraday_middleware' require 'faraday_middleware'
require "nokogiri" require 'nokogiri'
require 'manifique/metadata' require 'manifique/metadata'
require 'manifique/errors'
module Manifique module Manifique
class WebClient class WebClient
@ -160,8 +161,10 @@ module Manifique
if res.status < 400 if res.status < 400
res res
else else
raise "Could not fetch #{url} successfully (#{res.status})" raise Manifique::Error.new "Failed with HTTP status #{res.status}", "http_#{res.status}", url
end end
rescue Faraday::ConnectionFailed, Faraday::TimeoutError, Faraday::SSLError => e
raise Manifique::Error.new "Failed to connect", "connection_failed", url
end end
def discover_web_manifest_url(html) def discover_web_manifest_url(html)

View File

@ -13,6 +13,13 @@ RSpec.describe Manifique::WebClient do
stub_request(:get, "http://example.com/200_empty"). stub_request(:get, "http://example.com/200_empty").
to_return(body: "", status: 200, headers: {}) to_return(body: "", status: 200, headers: {})
stub_request(:get, "http://example.com/failed").
to_raise(Faraday::ConnectionFailed)
stub_request(:get, "http://example.com/timeout").
to_raise(Faraday::TimeoutError)
stub_request(:get, "http://example.com/ssl_error").
to_raise(Faraday::SSLError)
end end
context "unsuccessful requests" do context "unsuccessful requests" do
@ -22,7 +29,12 @@ RSpec.describe Manifique::WebClient do
it "raises an exception" do it "raises an exception" do
expect { expect {
client.send(:do_get_request, 'http://example.com/404') client.send(:do_get_request, 'http://example.com/404')
}.to raise_error("Could not fetch http://example.com/404 successfully (404)") }.to raise_error { |error|
expect(error).to be_a(Manifique::Error)
expect(error.message).to eq("Failed with HTTP status 404")
expect(error.type).to eq("http_404")
expect(error.url).to eq("http://example.com/404")
}
end end
end end
@ -32,7 +44,39 @@ RSpec.describe Manifique::WebClient do
it "raises an exception" do it "raises an exception" do
expect { expect {
client.send(:do_get_request, 'http://example.com/500') client.send(:do_get_request, 'http://example.com/500')
}.to raise_error("Could not fetch http://example.com/500 successfully (500)") }.to raise_error { |error|
expect(error).to be_a(Manifique::Error)
expect(error.message).to eq("Failed with HTTP status 500")
expect(error.type).to eq("http_500")
expect(error.url).to eq("http://example.com/500")
}
end
end
describe "failed connections" do
let(:client) { Manifique::WebClient.new }
it "raises an exception on connection failures" do
expect {
client.send(:do_get_request, 'http://example.com/failed')
}.to raise_error { |error|
expect(error).to be_a(Manifique::Error)
expect(error.message).to eq("Failed to connect")
expect(error.type).to eq("connection_failed")
expect(error.url).to eq("http://example.com/failed")
}
end
it "raises an exception on timouts" do
expect {
client.send(:do_get_request, 'http://example.com/timeout')
}.to raise_error("Failed to connect")
end
it "raises an exception on SSL errors" do
expect {
client.send(:do_get_request, 'http://example.com/ssl_error')
}.to raise_error("Failed to connect")
end end
end end
end end