Skip to content

Commit 72c02c3

Browse files
feat: expose response headers for both streams and errors
1 parent 9aaa659 commit 72c02c3

File tree

9 files changed

+80
-29
lines changed

9 files changed

+80
-29
lines changed

lib/imagekit/errors.rb

Lines changed: 25 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,25 @@ class APIError < Imagekit::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 < Imagekit::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 < Imagekit::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,21 +125,24 @@ class APIStatusError < Imagekit::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)
126-
kwargs = {
127-
url: url,
128-
status: status,
129-
body: body,
130-
request: request,
131-
response: response,
132-
message: message
133-
}
135+
def self.for(url:, status:, headers:, body:, request:, response:, message: nil)
136+
kwargs =
137+
{
138+
url: url,
139+
status: status,
140+
headers: headers,
141+
body: body,
142+
request: request,
143+
response: response,
144+
message: message
145+
}
134146

135147
case status
136148
in 400
@@ -162,15 +174,17 @@ def self.for(url:, status:, body:, request:, response:, message: nil)
162174
#
163175
# @param url [URI::Generic]
164176
# @param status [Integer]
177+
# @param headers [Hash{String=>String}, nil]
165178
# @param body [Object, nil]
166179
# @param request [nil]
167180
# @param response [nil]
168181
# @param message [String, nil]
169-
def initialize(url:, status:, body:, request:, response:, message: nil)
182+
def initialize(url:, status:, headers:, body:, request:, response:, message: nil)
170183
message ||= {url: url.to_s, status: status, body: body}
171184
super(
172185
url: url,
173186
status: status,
187+
headers: headers,
174188
body: body,
175189
request: request,
176190
response: response,

lib/imagekit/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:)
@@ -378,6 +378,7 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
378378
rescue Imagekit::Errors::APIConnectionError => e
379379
status = e
380380
end
381+
headers = Imagekit::Internal::Util.normalized_headers(response&.each_header&.to_h)
381382

382383
case status
383384
in ..299
@@ -390,7 +391,7 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
390391
in 300..399
391392
self.class.reap_connection!(status, stream: stream)
392393

393-
request = self.class.follow_redirect(request, status: status, response_headers: response)
394+
request = self.class.follow_redirect(request, status: status, response_headers: headers)
394395
send_request(
395396
request,
396397
redirect_count: redirect_count + 1,
@@ -399,16 +400,17 @@ def send_request(request, redirect_count:, retry_count:, send_retry_header:)
399400
)
400401
in Imagekit::Errors::APIConnectionError if retry_count >= max_retries
401402
raise status
402-
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: response)
403+
in (400..) if retry_count >= max_retries || !self.class.should_retry?(status, headers: headers)
403404
decoded = Kernel.then do
404-
Imagekit::Internal::Util.decode_content(response, stream: stream, suppress_error: true)
405+
Imagekit::Internal::Util.decode_content(headers, stream: stream, suppress_error: true)
405406
ensure
406407
self.class.reap_connection!(status, stream: stream)
407408
end
408409

409410
raise Imagekit::Errors::APIStatusError.for(
410411
url: url,
411412
status: status,
413+
headers: headers,
412414
body: decoded,
413415
request: nil,
414416
response: response
@@ -485,19 +487,21 @@ def request(req)
485487
send_retry_header: send_retry_header
486488
)
487489

488-
decoded = Imagekit::Internal::Util.decode_content(response, stream: stream)
490+
headers = Imagekit::Internal::Util.normalized_headers(response.each_header.to_h)
491+
decoded = Imagekit::Internal::Util.decode_content(headers, stream: stream)
489492
case req
490493
in {stream: Class => st}
491494
st.new(
492495
model: model,
493496
url: url,
494497
status: status,
498+
headers: headers,
495499
response: response,
496500
unwrap: unwrap,
497501
stream: decoded
498502
)
499503
in {page: Class => page}
500-
page.new(client: self, req: req, headers: response, page_data: decoded)
504+
page.new(client: self, req: req, headers: headers, page_data: decoded)
501505
else
502506
unwrapped = Imagekit::Internal::Util.dig(decoded, unwrap)
503507
Imagekit::Internal::Type::Converter.coerce(model, unwrapped)

lib/imagekit/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 [Imagekit::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/imagekit/internal/util.rb

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

rbi/imagekit/errors.rbi

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ module Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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 Imagekit
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/imagekit/internal/transport/base_client.rbi

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,9 @@ module Imagekit
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 Imagekit
9796
params(
9897
request: Imagekit::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(Imagekit::Internal::Transport::BaseClient::RequestInput)
102101
end
103102
def follow_redirect(request, status:, response_headers:)

rbi/imagekit/internal/type/base_page.rbi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ module Imagekit
3030
params(
3131
client: Imagekit::Internal::Transport::BaseClient,
3232
req: Imagekit::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/imagekit/internal/util.rbi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ module Imagekit
361361
# Assumes each chunk in stream has `Encoding::BINARY`.
362362
sig do
363363
params(
364-
headers: T.any(T::Hash[String, String], Net::HTTPHeader),
364+
headers: T::Hash[String, String],
365365
stream: T::Enumerable[String],
366366
suppress_error: T::Boolean
367367
).returns(T.anything)

0 commit comments

Comments
 (0)