-
-
Notifications
You must be signed in to change notification settings - Fork 1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevent ActiveJob::DeserializationError when looking for active jobs with specific arguments in the queue #2036
Prevent ActiveJob::DeserializationError when looking for active jobs with specific arguments in the queue #2036
Conversation
…ith specific arguments if one of the active jobs in the queue have undeserializable arguments
@@ -169,6 +173,10 @@ def set_expected_number(relativity, count) | |||
end | |||
end | |||
|
|||
def deserialize_arguments(job) | |||
::ActiveJob::Arguments.deserialize(job[:args]) rescue nil |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we can't deserialize the args, the most we should do is return the original args.
if deserialized_args | ||
RSpec::Mocks::ArgumentListMatcher.new(*@args).args_match?(*deserialized_args) | ||
else | ||
false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we return the original arguments we avoid the if
@@ -98,7 +98,7 @@ def supports_block_expectations? | |||
def check(jobs) | |||
@matching_jobs, @unmatching_jobs = jobs.partition do |job| | |||
if arguments_match?(job) && other_attributes_match?(job) | |||
args = ::ActiveJob::Arguments.deserialize(job[:args]) | |||
args = deserialize_arguments(job) || [] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't need an || []
if we leave the original args as a replacement
@@ -125,7 +125,7 @@ def base_message | |||
|
|||
def base_job_message(job) | |||
msg_parts = [] | |||
msg_parts << "with #{::ActiveJob::Arguments.deserialize(job[:args])}" if job[:args].any? | |||
msg_parts << "with #{deserialize_arguments(job) || job[:args].inspect}" if job[:args].any? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also won't need the ||
if we return the original args
@@ -169,6 +169,10 @@ def set_expected_number(relativity, count) | |||
end | |||
end | |||
|
|||
def deserialize_arguments(job) | |||
::ActiveJob::Arguments.deserialize(job[:args]) rescue job[:args] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we want to only rescue ActiveJob::DeserializationError
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch, yes we do.
…zation of arguments
::ActiveJob::Arguments.deserialize(job[:args]) | ||
rescue ::ActiveJob::DeserializationError | ||
job[:args] | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use the inline form of rescue here:
def deserialize_arguments(job)
::ActiveJob::Arguments.deserialize(job[:args])
rescue ::ActiveJob::DeserializationError
job[:args]
end
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In fact you'll need to in order to satisfy Rubocop!
After this #2036 (comment) LGTM 🎉 Thanks for the PR |
Thanks, will merge when green |
…bs (#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).
…bs (rspec#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).
…bs (rspec#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).
When running a test expecting to find active jobs in the queue with specific arguments, the have_enqueued_job.with and have_been_enqueued.with matchers will iterate over each queued active jobs, deserialize its arguments and check if it matches the expected value. However, the deserialization of some arguments may raise an ActiveJob::DeserializationError, for example for jobs having destroyed active records as arguments.
This is an issue since some active jobs may be generated by some code that we are not testing but will make our test fail since we have to deserialize their arguments anyway.
This PR prevents this crash from happening by rescuing all the raised ActiveJob::DeserializationError in the matcher when deserializing arguments. This operation is done at 3 different places: