From f71cfb57e4986c50c47e649e9c53893e10bcb157 Mon Sep 17 00:00:00 2001 From: Joe Yates Date: Mon, 10 Jun 2024 09:57:44 +0200 Subject: [PATCH] Handle multi fetch failure gracefully --- lib/imap/backup/flag_refresher.rb | 7 +++++++ lib/imap/backup/version.rb | 2 +- spec/unit/flag_refresher_spec.rb | 33 +++++++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 spec/unit/flag_refresher_spec.rb diff --git a/lib/imap/backup/flag_refresher.rb b/lib/imap/backup/flag_refresher.rb index d9d45017..cb24195e 100644 --- a/lib/imap/backup/flag_refresher.rb +++ b/lib/imap/backup/flag_refresher.rb @@ -28,6 +28,13 @@ def run def refresh_block(uids) uids_and_flags = folder.fetch_multi(uids, ["FLAGS"]) + if !uids_and_flags + Logger.logger.debug( + "[#{folder.name}] failed to fetch flags for #{uids} - " \ + "cannot refresh flags" + ) + return + end uids_and_flags.each do |uid_and_flags| uid = uid_and_flags[:uid] flags = uid_and_flags[:flags] diff --git a/lib/imap/backup/version.rb b/lib/imap/backup/version.rb index 926e9e5a..a2b23dec 100644 --- a/lib/imap/backup/version.rb +++ b/lib/imap/backup/version.rb @@ -6,7 +6,7 @@ module Imap::Backup # @private MINOR = 0 # @private - REVISION = 1 + REVISION = 2 # @private PRE = nil # The application version diff --git a/spec/unit/flag_refresher_spec.rb b/spec/unit/flag_refresher_spec.rb new file mode 100644 index 00000000..57812139 --- /dev/null +++ b/spec/unit/flag_refresher_spec.rb @@ -0,0 +1,33 @@ +require "imap/backup/account/folder" +require "imap/backup/flag_refresher" +require "imap/backup/serializer" + +module Imap::Backup + RSpec.describe FlagRefresher do + subject { described_class.new(folder, serializer) } + + let(:serializer) { instance_double(Serializer, uids: [1, 2]) } + let(:folder) { instance_double(Account::Folder, uids: [2], name: "my_folder") } + + it "refreshes the flags" do + response = [{uid: 1, flags: [:Draft]}, {uid: 2, flags: [:Seen]}] + allow(folder).to receive(:fetch_multi).with([1, 2], ["FLAGS"]) { response } + + expect(serializer).to receive(:update).with(1, flags: [:Draft]) + expect(serializer).to receive(:update).with(2, flags: [:Seen]) + + subject.run + end + + context "when the fetch fails" do + it "logs a warning" do + allow(folder).to receive(:fetch_multi).with([1, 2], ["FLAGS"]).and_return(nil) + expect(Logger.logger). + to receive(:debug). + with("[#{folder.name}] failed to fetch flags for [1, 2] - cannot refresh flags") + + subject.run + end + end + end +end