Skip to content

Commit db6863a

Browse files
authored
feat: add raise_error feature (#792)
1 parent 470203f commit db6863a

File tree

5 files changed

+98
-1
lines changed

5 files changed

+98
-1
lines changed

lib/http/chainable.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,7 @@ def nodelay
243243
# * instrumentation
244244
# * logging
245245
# * normalize_uri
246+
# * raise_error
246247
# @param features
247248
def use(*features)
248249
branch default_options.with_features(features)

lib/http/errors.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,17 @@ class ResponseError < Error; end
2121
# Requested to do something when we're in the wrong state
2222
class StateError < ResponseError; end
2323

24+
# When status code indicates an error
25+
class StatusError < ResponseError
26+
attr_reader :response
27+
28+
def initialize(response)
29+
@response = response
30+
31+
super("Unexpected status code #{response.code}")
32+
end
33+
end
34+
2435
# Generic Timeout error
2536
class TimeoutError < Error; end
2637

lib/http/feature.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ def on_error(_request, _error); end
1616

1717
require "http/features/auto_inflate"
1818
require "http/features/auto_deflate"
19-
require "http/features/logging"
2019
require "http/features/instrumentation"
20+
require "http/features/logging"
2121
require "http/features/normalize_uri"
22+
require "http/features/raise_error"

lib/http/features/raise_error.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# frozen_string_literal: true
2+
3+
module HTTP
4+
module Features
5+
class RaiseError < Feature
6+
def initialize(ignore: [])
7+
super()
8+
9+
@ignore = ignore
10+
end
11+
12+
def wrap_response(response)
13+
return response if response.code < 400
14+
return response if @ignore.include?(response.code)
15+
16+
raise HTTP::StatusError, response
17+
end
18+
19+
HTTP::Options.register_feature(:raise_error, self)
20+
end
21+
end
22+
end
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
# frozen_string_literal: true
2+
3+
RSpec.describe HTTP::Features::RaiseError do
4+
subject(:feature) { described_class.new(ignore: ignore) }
5+
6+
let(:connection) { double }
7+
let(:status) { 200 }
8+
let(:ignore) { [] }
9+
10+
describe "#wrap_response" do
11+
subject(:result) { feature.wrap_response(response) }
12+
13+
let(:response) do
14+
HTTP::Response.new(
15+
version: "1.1",
16+
status: status,
17+
headers: {},
18+
connection: connection,
19+
request: HTTP::Request.new(verb: :get, uri: "https://example.com")
20+
)
21+
end
22+
23+
context "when status is 200" do
24+
it "returns original request" do
25+
expect(result).to be response
26+
end
27+
end
28+
29+
context "when status is 399" do
30+
let(:status) { 399 }
31+
32+
it "returns original request" do
33+
expect(result).to be response
34+
end
35+
end
36+
37+
context "when status is 400" do
38+
let(:status) { 400 }
39+
40+
it "raises" do
41+
expect { result }.to raise_error(HTTP::StatusError, "Unexpected status code 400")
42+
end
43+
end
44+
45+
context "when status is 599" do
46+
let(:status) { 599 }
47+
48+
it "raises" do
49+
expect { result }.to raise_error(HTTP::StatusError, "Unexpected status code 599")
50+
end
51+
end
52+
53+
context "when error status is ignored" do
54+
let(:status) { 500 }
55+
let(:ignore) { [500] }
56+
57+
it "returns original request" do
58+
expect(result).to be response
59+
end
60+
end
61+
end
62+
end

0 commit comments

Comments
 (0)