ActiveJob::DeserializationError: Error while trying to deserialize arguments
Asked Answered
D

2

11

I am trying to send mail in production but it is throwing Activejob deserailization error.sidekiq is running in background. I have added sidekiq gem. I wrote one method in comment_notification.rb for sending email to the user. Then in controller in create action I have added this

def create
    CommentNotification.send_comment_mail(@current_user).deliver_later(wait: 1.minute)
end


def send_comment_email(current_user)
    mail( to: current_user.email,
    :subject => "commented on post",
    :from => "<[email protected]>")
end

It was working fine in local server but in production I am getting this error

/home/apps/commentpost/shared/bundle/ruby/2.3.0/gems/sidekiq-4.2.3/lib/sidekiq/processor.rb:69:in `run'
/home/apps/commentpost/shared/bundle/ruby/2.3.0/gems/sidekiq-4.2.3/lib/sidekiq/util.rb:17:in `watchdog'
/home/apps/commentpost/shared/bundle/ruby/2.3.0/gems/sidekiq-4.2.3/lib/sidekiq/util.rb:25:in `block in safe_thread'
2016-11-18T06:47:16.162Z 19093 TID-uw66g ActionMailer::DeliveryJob JID-e56b150964abf082e78089d9 INFO: start
2016-11-18T06:47:16.167Z 19093 TID-uw66g ActionMailer::DeliveryJob JID-e56b150964abf082e78089d9 INFO: fail: 0.005 sec
2016-11-18T06:47:16.167Z 19093 TID-uw66g WARN: {"context":"Job raised exception","job":{"class":"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper","wrapped":"ActionMailer::DeliveryJob","queue":"mailers","args":[{"job_class":"ActionMailer::DeliveryJob","job_id":"96e06bc6-1380-47b9-9393-9727868b3897","queue_name":"mailers","priority":null,"arguments":["CommentNotification","send_comment_email","deliver_later",{"_aj_globalid":"gid://commentpost/comment/40"},{"_aj_globalid":"gid://commentpost/User/20"}],"locale":"en"}],"retry":true,"jid":"e56b150964abf082e78089d9","created_at":1479450405.8364522,"enqueued_at":1479451636.1602836,"error_message":"Error while trying to deserialize arguments: Couldn't find Comment with 'id'=40","error_class":"ActiveJob::DeserializationError","failed_at":1479450405.8429642,"retry_count":6,"retried_at":1479451636.1668367},"jobstr":"{\"class\":\"ActiveJob::QueueAdapters::SidekiqAdapter::JobWrapper\",\"wrapped\":\"ActionMailer::DeliveryJob\",\"queue\":\"mailers\",\"args\":[{\"job_class\":\"ActionMailer::DeliveryJob\",\"job_id\":\"96e06bc6-1380-47b9-9393-9727868b3897\",\"queue_name\":\"mailers\",\"priority\":null,\"arguments\":[\"CommentNotification\",\"send_comment_email\",\"deliver_later\",{\"_aj_globalid\":\"gid://commentpost/comment/40\"},{\"_aj_globalid\":\"gid://commentpost/User/20\"}],\"locale\":\"en\"}],\"retry\":true,\"jid\":\"e56b150964abf082e78089d9\",\"created_at\":1479450405.8364522,\"enqueued_at\":1479451636.1602836,\"error_message\":\"Error while trying to deserialize arguments: Couldn't find Comment with 'id'=40\",\"error_class\":\"ActiveJob::DeserializationError\",\"failed_at\":1479450405.8429642,\"retry_count\":5,\"retried_at\":1479450981.998904}"}
2016-11-18T06:47:16.167Z 19093 TID-uw66g WARN: ActiveJob::DeserializationError: Error while trying to deserialize arguments: Couldn't find Comment with 'id'=40
2016-11-18T06:47:16.167Z 19093 TID-uw66g WARN: /

Could anyone please help me regarding this doubt? For this I will be thankful.

Denotative answered 18/11, 2016 at 8:14 Comment(2)
Now, when you posted the error, read it, especially this part Error while trying to deserialize arguments: Couldn't find Comment with 'id'=40. Doesn't it give you a hint on solving the problem?Hiss
id is there in database with 40 and comment is also creating. the only issue is that mail is not getting triggred.Denotative
M
10

As I understand correctly the create method in controller creates also the comment and sends the email for the freshly created comment?

Then it would be better to use a callback here.
We had the same issue in our project and we solved it by using something like that:

# in model
after_commit :send_mail, on: :create

private

def send_mail
  CommentNotification.send_comment_mail(campaign.user).deliver_later
end

Then you can be sure that the record really exists in the Database before the mail gets delivered.

The problem here is, that you run a Comment#create and enqueue the mail in the controller. Now it can happen, that Sidekiq runs the task before Rails commits the new comment.
And then you get exactly this error.

Regards,
spa

Macaluso answered 18/11, 2016 at 10:36 Comment(5)
Can we write it in controller? eg : after_action :send email ,only: [:create]Denotative
You can. But you should use CommentNotification.send_comment_mail(campaign.user).deliver_later(wait: 5.minutes) or similar then.Macaluso
for both after_commit and the above methods are not working. still showing same error.Denotative
Then can you please update your question providing the real create action in controller and your #send_comment_mail method in the mailer?Macaluso
Looks good. from in the mail method should be just an email address without the surrounding "<". Can you please try to set the wait parameter to 10 minutes or more. Just to see if your database is very slow. And if this doesn't help, can you please post your mail view? Just to check if the problem is in there. Is your database on another server in production?Macaluso
K
1

When I ran into an issue with seemingly simple errors being raised due to the record not being the database (it was!), I found out that my Sidekiq workers were running in test mode and were able to dequeue jobs whose database records were supposed to be in the development database.

I was able to debug this after some trial and error in the stack trace by inspecting ActiveRecord::Base.connection's connection_parameters instance variable - it was pointing to the test database!

Looking through the Sidekiq logs, I was able to see that it was starting up workers to execute jobs against the test environment and database. My specific issue was also caused by spring. Disabling its use by invoking bundle exec sidekiq ... instead of sprint sidekiq fixed my issue.

Kurgan answered 25/8, 2021 at 20:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.