Skip to content

Commit 215d4cd

Browse files
committed
reverted the revert, but added an option to restore old behavior
1 parent afbe9de commit 215d4cd

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
The "really niche bugfix" edition:
44

5+
* don't stop fetching in `fetch_all` if an empty page is returned but the cursor is not nil; it's technically allowed for the server to return an empty page but still have more data to send, e.g. if the service does some filtering at the last step and all records happen to be filtered out
6+
- unfortunately, this causes problems with some specific endpoints which incorrectly return a cursor when reaching the end of data, so you can restore the previous behavior by setting the `stop_fetch_on_empty_page` option
57
* in `post_request`, don't set Content-Type to "application/json" if the data sent is a string or nil (it might cause an error in some cases, like when uploading some binary content)
68
* handle the (somewhat theoretical but possible) case where an access token is not a JWT but just some opaque blob – in that case, Minisky will now not throw an error trying to parse it, but just treat it as "unknown" and will not try to refresh it
79
- note: at the moment Minisky will not catch the "token expired" error and refresh the token automatically in such scenario

lib/minisky/requests.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,16 @@ module Requests
5050
#
5151
attr_accessor :default_progress
5252

53+
# By default, when `fetch_all` receives a response with an empty page with no records but
54+
# which includes a cursor for the next page, it keeps fetching until it receives a response
55+
# with null cursor. This is more technically correct, but can cause problems with some
56+
# non-compliant APIs, so you can set this option to stop fetching when an empty page
57+
# is received.
58+
#
59+
# @return [Boolean]
60+
#
61+
attr_accessor :stop_fetch_on_empty_page
62+
5363
attr_writer :send_auth_headers
5464
attr_writer :auto_manage_tokens
5565

@@ -285,10 +295,7 @@ def fetch_all(method, params = nil, auth: default_auth_mode,
285295
params[:cursor] = cursor
286296
pages += 1
287297

288-
# TODO: don't break if records.empty? but cursor != nil
289-
# but currently this causes problems with some Bluesky endpoints like getBookmarks
290-
291-
break if !cursor || records.empty? || pages == max_pages
298+
break if !cursor || pages == max_pages || (stop_fetch_on_empty_page && records.empty?)
292299
break if break_when && records.any? { |x| break_when.call(x) }
293300
end
294301

spec/shared/ex_fetch_all.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,21 @@
218218
result = subject.fetch_all('com.example.service.fetchAll', field: 'feed')
219219
result.should == ['one', 'two', 'three', 'six']
220220
end
221+
222+
context 'with stop_fetch_on_empty_page option set to true' do
223+
before do
224+
subject.stop_fetch_on_empty_page = true
225+
end
226+
227+
it 'should stop at the first empty page' do
228+
result = subject.fetch_all('com.example.service.fetchAll', field: 'feed')
229+
result.should == ['one', 'two', 'three']
230+
231+
WebMock.should have_requested(:get, @stubbed_urls[0]).once
232+
WebMock.should have_requested(:get, @stubbed_urls[1]).once
233+
WebMock.should_not have_requested(:get, @stubbed_urls[2])
234+
end
235+
end
221236
end
222237

223238
context 'when field is not passed' do

0 commit comments

Comments
 (0)