Skip to content

Commit 9d7c82f

Browse files
aymeric-ledorzeJonRowe
authored andcommitted
Prevent ActiveJob::DeserializationError when deserialising expired jobs (#2036)
Prevents an exception from being raised when looking for an ActiveJob with specific arguments if one or more of the active jobs in the queue have arguments that cannot be deserialised (e.g. if the record has now been deleted).
1 parent afd1a59 commit 9d7c82f

File tree

2 files changed

+26
-4
lines changed

2 files changed

+26
-4
lines changed

lib/rspec/rails/matchers/active_job.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ def supports_block_expectations?
9898
def check(jobs)
9999
@matching_jobs, @unmatching_jobs = jobs.partition do |job|
100100
if arguments_match?(job) && other_attributes_match?(job)
101-
args = ::ActiveJob::Arguments.deserialize(job[:args])
101+
args = deserialize_arguments(job)
102102
@block.call(*args)
103103
true
104104
else
@@ -125,7 +125,7 @@ def base_message
125125

126126
def base_job_message(job)
127127
msg_parts = []
128-
msg_parts << "with #{::ActiveJob::Arguments.deserialize(job[:args])}" if job[:args].any?
128+
msg_parts << "with #{deserialize_arguments(job)}" if job[:args].any?
129129
msg_parts << "on queue #{job[:queue]}" if job[:queue]
130130
msg_parts << "at #{Time.at(job[:at])}" if job[:at]
131131

@@ -136,7 +136,7 @@ def base_job_message(job)
136136

137137
def arguments_match?(job)
138138
if @args.any?
139-
deserialized_args = ::ActiveJob::Arguments.deserialize(job[:args])
139+
deserialized_args = deserialize_arguments(job)
140140
RSpec::Mocks::ArgumentListMatcher.new(*@args).args_match?(*deserialized_args)
141141
else
142142
true
@@ -169,6 +169,12 @@ def set_expected_number(relativity, count)
169169
end
170170
end
171171

172+
def deserialize_arguments(job)
173+
::ActiveJob::Arguments.deserialize(job[:args])
174+
rescue ::ActiveJob::DeserializationError
175+
job[:args]
176+
end
177+
172178
def queue_adapter
173179
::ActiveJob::Base.queue_adapter
174180
end

spec/rspec/rails/matchers/active_job_spec.rb

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ def initialize(id)
1818
end
1919

2020
def ==(comparison_object)
21-
id == comparison_object.id
21+
(GlobalIdModel === comparison_object) && (id == comparison_object.id)
2222
end
2323

2424
def to_global_id(options = {})
2525
@global_id ||= GlobalID.create(self, :app => "rspec-suite")
2626
end
2727
end
28+
29+
class FailingGlobalIdModel < GlobalIdModel
30+
def self.find(id)
31+
raise URI::GID::MissingModelIdError
32+
end
33+
end
2834
end
2935

3036
RSpec.describe "ActiveJob matchers", :skip => !RSpec::Rails::FeatureCheck.has_active_job? do
@@ -293,6 +299,16 @@ def self.name; "LoggingJob"; end
293299
}
294300
end
295301

302+
it "ignores undeserializable arguments" do
303+
failing_global_id_object = FailingGlobalIdModel.new("21")
304+
global_id_object = GlobalIdModel.new("42")
305+
306+
expect{
307+
hello_job.perform_later(failing_global_id_object)
308+
hello_job.perform_later(global_id_object)
309+
}.to have_enqueued_job(hello_job).with(global_id_object)
310+
end
311+
296312
it "only calls with block if other conditions are met" do
297313
noon = Date.tomorrow.noon
298314
midnight = Date.tomorrow.midnight

0 commit comments

Comments
 (0)