Skip to content

Commit cafba93

Browse files
feat: expose response headers for both streams and errors
1 parent b89ea6d commit cafba93

File tree

10 files changed

+81
-30
lines changed

10 files changed

+81
-30
lines changed

lib/orb/errors.rb

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,25 @@ class APIError < Orb::Errors::Error
4040
# @return [Integer, nil]
4141
attr_accessor :status
4242

43+
# @return [Hash{String=>String}, nil]
44+
attr_accessor :headers
45+
4346
# @return [Object, nil]
4447
attr_accessor :body
4548

4649
# @api private
4750
#
4851
# @param url [URI::Generic]
4952
# @param status [Integer, nil]
53+
# @param headers [Hash{String=>String}, nil]
5054
# @param body [Object, nil]
5155
# @param request [nil]
5256
# @param response [nil]
5357
# @param message [String, nil]
54-
def initialize(url:, status: nil, body: nil, request: nil, response: nil, message: nil)
58+
def initialize(url:, status: nil, headers: nil, body: nil, request: nil, response: nil, message: nil)
5559
@url = url
5660
@status = status
61+
@headers = headers
5762
@body = body
5863
@request = request
5964
@response = response
@@ -74,13 +79,15 @@ class APIConnectionError < Orb::Errors::APIError
7479
#
7580
# @param url [URI::Generic]
7681
# @param status [nil]
82+
# @param headers [Hash{String=>String}, nil]
7783
# @param body [nil]
7884
# @param request [nil]
7985
# @param response [nil]
8086
# @param message [String, nil]
8187
def initialize(
8288
url:,
8389
status: nil,
90+
headers: nil,
8491
body: nil,
8592
request: nil,
8693
response: nil,
@@ -95,13 +102,15 @@ class APITimeoutError < Orb::Errors::APIConnectionError
95102
#
96103
# @param url [URI::Generic]
97104
# @param status [nil]
105+
# @param headers [Hash{String=>String}, nil]
98106
# @param body [nil]
99107
# @param request [nil]
100108
# @param response [nil]
101109
# @param message [String, nil]
102110
def initialize(
103111
url:,
104112
status: nil,
113+
headers: nil,
105114
body: nil,
106115
request: nil,
107116
response: nil,
@@ -116,22 +125,25 @@ class APIStatusError < Orb::Errors::APIError
116125
#
117126
# @param url [URI::Generic]
118127
# @param status [Integer]
128+
# @param headers [Hash{String=>String}, nil]
119129
# @param body [Object, nil]
120130
# @param request [nil]
121131
# @param response [nil]
122132
# @param message [String, nil]
123133
#
124134
# @return [self]
125-
def self.for(url:, status:, body:, request:, response:, message: nil)
135+
def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
126136
key = Orb::Internal::Util.dig(body, :type)
127-
kwargs = {
128-
url: url,
129-
status: status,
130-
body: body,
131-
request: request,
132-
response: response,
133-
message: message
134-
}
137+
kwargs =
138+
{
139+
url: url,
140+
status: status,
141+
headers: headers,
142+
body: body,
143+
request: request,
144+
response: response,
145+
message: message
146+
}
135147

136148
case [status, key]
137149
in [400, Orb::Errors::ConstraintViolation::TYPE]
@@ -187,15 +199,17 @@ def self.for(url:, status:, body:, request:, response:, message: nil)
187199
#
188200
# @param url [URI::Generic]
189201
# @param status [Integer]
202+
# @param headers [Hash{String=>String}, nil]
190203
# @param body [Object, nil]
191204
# @param request [nil]
192205
# @param response [nil]
193206
# @param message [String, nil]
194-
def initialize(url:, status:, body:, request:, response:, message: nil)
207+
def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
195208
message ||= {url: url.to_s, status: status, body: body}
196209
super(
197210
url: url,
198211
status: status,
212+
headers: headers,
199213
body: body,
200214
request: request,
201215
response: response,

lib/orb/internal/page.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def auto_paging_each(&blk)
6060
#
6161
# @param client [Orb::Internal::Transport::BaseClient]
6262
# @param req [Hash{Symbol=>Object}]
63-
# @param headers [Hash{String=>String}, Net::HTTPHeader]
63+
# @param headers [Hash{String=>String}]
6464
# @param page_data [Hash{Symbol=>Object}]
6565
def initialize(client:, req:, headers:, page_data:)
6666
super

lib/orb/internal/transport/base_client.rb

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def validate!(req)
4747
# @api private
4848
#
4949
# @param status [Integer]
50-
# @param headers [Hash{String=>String}, Net::HTTPHeader]
50+
# @param headers [Hash{String=>String}]
5151
#
5252
# @return [Boolean]
5353
def should_retry?(status, headers:)
@@ -85,7 +85,7 @@ def should_retry?(status, headers:)
8585
#
8686
# @param status [Integer]
8787
#
88-
# @param response_headers [Hash{String=>String}, Net::HTTPHeader]
88+
# @param response_headers [Hash{String=>String}]
8989
#
9090
# @return [Hash{Symbol=>Object}]
9191
def follow_redirect(request, status:, response_headers:)
@@ -375,6 +375,7 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
375375
rescue Orb::Errors::APIConnectionError => e
376376
status = e
377377
end
378+
headers = Orb::Internal::Util.normalized_headers(response&.each_header&.to_h)
378379

379380
case status
380381
in ..299
@@ -387,7 +388,7 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
387388
in 300..399
388389
self.class.reap_connection!(status, stream: stream)
389390

390-
request = self.class.follow_redirect(request, status: status, response_headers: response)
391+
request = self.class.follow_redirect(request, status: status, response_headers: headers)
391392
send_request(
392393
request,
393394
redirect_count: redirect_count + 1,
@@ -396,16 +397,17 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
396397
)
397398
in Orb::Errors::APIConnectionError if retry_count >= max_retries
398399
raise status
399-
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response)
400+
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
400401
decoded = Kernel.then do
401-
Orb::Internal::Util.decode_content(response, stream: stream, suppress_error: true)
402+
Orb::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
402403
ensure
403404
self.class.reap_connection!(status, stream: stream)
404405
end
405406

406407
raise Orb::Errors::APIStatusError.for(
407408
url: url,
408409
status: status,
410+
headers: headers,
409411
body: decoded,
410412
request: nil,
411413
response: response
@@ -482,19 +484,21 @@ def request(req)
482484
send_retry_header: send_retry_header
483485
)
484486

485-
decoded = Orb::Internal::Util.decode_content(response, stream: stream)
487+
headers = Orb::Internal::Util.normalized_headers(response.each_header.to_h)
488+
decoded = Orb::Internal::Util.decode_content(headers, stream: stream)
486489
case req
487490
in {stream: Class => st}
488491
st.new(
489492
model: model,
490493
url: url,
491494
status: status,
495+
headers: headers,
492496
response: response,
493497
unwrap: unwrap,
494498
stream: decoded
495499
)
496500
in {page: Class => page}
497-
page.new(client: self, req: req, headers: response, page_data: decoded)
501+
page.new(client: self, req: req, headers: headers, page_data: decoded)
498502
else
499503
unwrapped = Orb::Internal::Util.dig(decoded, unwrap)
500504
Orb::Internal::Type::Converter.coerce(model, unwrapped)

lib/orb/internal/type/base_page.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def to_enum = super(:auto_paging_each)
3939
#
4040
# @param client [Orb::Internal::Transport::BaseClient]
4141
# @param req [Hash{Symbol=>Object}]
42-
# @param headers [Hash{String=>String}, Net::HTTPHeader]
42+
# @param headers [Hash{String=>String}]
4343
# @param page_data [Object]
4444
def initialize(client:, req:, headers:, page_data:)
4545
@client = client

lib/orb/internal/util.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ def force_charset!(content_type, text:)
645645
#
646646
# Assumes each chunk in stream has `Encoding::BINARY`.
647647
#
648-
# @param headers [Hash{String=>String}, Net::HTTPHeader]
648+
# @param headers [Hash{String=>String}]
649649
# @param stream [Enumerable<String>]
650650
# @param suppress_error [Boolean]
651651
#

rbi/orb/errors.rbi

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ module Orb
3333
sig { returns(T.nilable(Integer)) }
3434
attr_accessor :status
3535

36+
sig { returns(T.nilable(T::Hash[String, String])) }
37+
attr_accessor :headers
38+
3639
sig { returns(T.nilable(T.anything)) }
3740
attr_accessor :body
3841

@@ -41,6 +44,7 @@ module Orb
4144
params(
4245
url: URI::Generic,
4346
status: T.nilable(Integer),
47+
headers: T.nilable(T::Hash[String, String]),
4448
body: T.nilable(Object),
4549
request: NilClass,
4650
response: NilClass,
@@ -50,6 +54,7 @@ module Orb
5054
def self.new(
5155
url:,
5256
status: nil,
57+
headers: nil,
5358
body: nil,
5459
request: nil,
5560
response: nil,
@@ -70,6 +75,7 @@ module Orb
7075
params(
7176
url: URI::Generic,
7277
status: NilClass,
78+
headers: T.nilable(T::Hash[String, String]),
7379
body: NilClass,
7480
request: NilClass,
7581
response: NilClass,
@@ -79,6 +85,7 @@ module Orb
7985
def self.new(
8086
url:,
8187
status: nil,
88+
headers: nil,
8289
body: nil,
8390
request: nil,
8491
response: nil,
@@ -93,6 +100,7 @@ module Orb
93100
params(
94101
url: URI::Generic,
95102
status: NilClass,
103+
headers: T.nilable(T::Hash[String, String]),
96104
body: NilClass,
97105
request: NilClass,
98106
response: NilClass,
@@ -102,6 +110,7 @@ module Orb
102110
def self.new(
103111
url:,
104112
status: nil,
113+
headers: nil,
105114
body: nil,
106115
request: nil,
107116
response: nil,
@@ -116,13 +125,22 @@ module Orb
116125
params(
117126
url: URI::Generic,
118127
status: Integer,
128+
headers: T.nilable(T::Hash[String, String]),
119129
body: T.nilable(Object),
120130
request: NilClass,
121131
response: NilClass,
122132
message: T.nilable(String)
123133
).returns(T.attached_class)
124134
end
125-
def self.for(url:, status:, body:, request:, response:, message: nil)
135+
def self.for(
136+
url:,
137+
status:,
138+
headers:,
139+
body:,
140+
request:,
141+
response:,
142+
message: nil
143+
)
126144
end
127145

128146
sig { returns(Integer) }
@@ -133,13 +151,22 @@ module Orb
133151
params(
134152
url: URI::Generic,
135153
status: Integer,
154+
headers: T.nilable(T::Hash[String, String]),
136155
body: T.nilable(Object),
137156
request: NilClass,
138157
response: NilClass,
139158
message: T.nilable(String)
140159
).returns(T.attached_class)
141160
end
142-
def self.new(url:, status:, body:, request:, response:, message: nil)
161+
def self.new(
162+
url:,
163+
status:,
164+
headers:,
165+
body:,
166+
request:,
167+
response:,
168+
message: nil
169+
)
143170
end
144171
end
145172

rbi/orb/internal/transport/base_client.rbi

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,9 @@ module Orb
8484

8585
# @api private
8686
sig do
87-
params(
88-
status: Integer,
89-
headers: T.any(T::Hash[String, String], Net::HTTPHeader)
90-
).returns(T::Boolean)
87+
params(status: Integer, headers: T::Hash[String, String]).returns(
88+
T::Boolean
89+
)
9190
end
9291
def should_retry?(status, headers:)
9392
end
@@ -97,7 +96,7 @@ module Orb
9796
params(
9897
request: Orb::Internal::Transport::BaseClient::RequestInput,
9998
status: Integer,
100-
response_headers: T.any(T::Hash[String, String], Net::HTTPHeader)
99+
response_headers: T::Hash[String, String]
101100
).returns(Orb::Internal::Transport::BaseClient::RequestInput)
102101
end
103102
def follow_redirect(request, status:, response_headers:)

rbi/orb/internal/type/base_page.rbi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Orb
3030
params(
3131
client: Orb::Internal::Transport::BaseClient,
3232
req: Orb::Internal::Transport::BaseClient::RequestComponents,
33-
headers: T.any(T::Hash[String, String], Net::HTTPHeader),
33+
headers: T::Hash[String, String],
3434
page_data: T.anything
3535
).void
3636
end

rbi/orb/internal/util.rbi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ module Orb
355355
# Assumes each chunk in stream has `Encoding::BINARY`.
356356
sig do
357357
params(
358-
headers: T.any(T::Hash[String, String], Net::HTTPHeader),
358+
headers: T::Hash[String, String],
359359
stream: T::Enumerable[String],
360360
suppress_error: T::Boolean
361361
).returns(T.anything)

0 commit comments

Comments
 (0)