Open the-teacher opened 8 years ago
@the-teacher I was able to reproduce the issue.
As you mentioned above, there is no easy way of using deliver_later
as exception_notification's code stands right now, but that should be easy to fix.
The real problem is the way the email is created and how ActiveJob
serializes the data to pass it to sidekiq.
When the environment section for the notification email is generated, it includes this:
* rack.input : #<StringIO:0x007fca9d87a6f8>
which seems to be the culprit.
Anyway I will investigate more and try to find a workaround to send emails in the background since it seems to be a good feature to support.
When serializing, ActiveJob
only support certain type of objects, according to the SerializationError docs:
Raised when an unsupported argument type is set as a job argument. We currently support NilClass, Fixnum, Float, String, TrueClass, FalseClass, Bignum, BigDecimal, and objects that can be represented as GlobalIDs (ex: Active Record). Raised if you set the key for a Hash something else than a string or a symbol. Also raised when trying to serialize an object which can't be identified with a Global ID - such as an unpersisted Active Record model.
Furthermore rack.input
is the first of many "unserializable" objects,
I thinks this leaves a few questions open.
create_email
?EmailNotifier
to get those objects without serialization?@Axxiss Did you find answers of your question? :) I have similar questions and got stuck.
@aruprakshit No, I didn't had a chance to look further into it.
This should be a great addition. I was wondering if it would be possible to serialize the data used in the views. I'm not familiar with the source code, but if anyone point me a direction I can give a shoot.
I ran into this exact issue in my application. It turned out the cause is ActiveJob saving parameters to later call the original method. My solution is to use Marshal.dump
on all parameters so that ActiveJob is given only a string (plus I put all parameters into an array to make it simpler). To demonstrate it on the code from the first post (untested, but should work):
module ExceptionNotifier
class EmailNotifier
def call(exception, options={})
create_email(Marshal.dump([ exception, options ])).deliver_later
end
def create_email(params)
super(*Marshal.load(params)))
end
end
end
Nice thing is that the (un)marshalling can be there even for non-delayed delivery. I hope this helps someone. :c)
@xHire I did that way you did. But while loading sometime I was getting encoding error.
@aruprakshit That’s interesting. Could you be more specific? Is it a normal Ruby encoding error or something special? For which encodings/contents does it happen?
Personally, I didn’t run in any such issue, but that might be because my application only works with ascii-8bit data.
2018, still looking for a way to have notifications perfomed by sikekiq...
Trying all solutions above, don't find something working yet.
It's gonna end with a custom message base on excpetion
and options
variables for me :/
Hi, I just got stuck with this. I tried many things, so far this is the best approach I have:
module EmailNotifier
def call(exception, options = {})
options[:env] = options[:env].transform_values do |value| # this could be in a pre_callback?
break if ActiveJob::Serializers.serializers.include? value.class
value.to_s
end
super(exception, options)
end
end
The problem with this approach, is have to write the serializers (see) for the classes that will used later for construct the body of email, (e.g. controller classes) and then add to active job serializers array. And only will work for Rails > 6.
Another approach its serialize to hashes the exception and options just before call deliver_later (maybe the email will have less info about the error).
What do you think?
This also hit me in a new Rails 6.1 app. Being able to deliver exception notifications in the background is important, and we use Sidekiq to back ActiveJob. I haven't found a good solution yet.
Would love to get a fix for this @juanazam! Thanks
+1
I have the same problem. When I use sidekiq I see An error occurred when sending a notification using 'email' notifier.ActiveJob::SerializationError: Unsupported argument type: IO
.
A slightly modified @kadru's version that worked for us on rails 6.1
config/initializers/exception_notifier.rb
module ExceptionNotifier
# ...
class EmailNotifier < BaseNotifier
def call_with_patch(exception, options = {})
options[:env] = options[:env].transform_values do |value|
break if ActiveJob::Serializers.serializers.include? value.class
value.to_s
end
call_without_patch(exception, options)
end
alias_method(:call_without_patch, :call)
alias_method(:call, :call_with_patch)
# ...
end
end
Hello! I am looking for way how to put sending notifications to the background.
I tried play with
exception_notification (4.1.4)
. I found option for email notificationsdeliver_with
but it looks like allow the justdeliver_now
value.Fine, I wrote following monkey patch for my test app:
config/initializers/exception_notifier_patch.rb
And I have an error message for Sidekiq:
So, for me it looks like
create_email
do something incorrect for delayed processors. Maybe DelayedJob can process this, but Sidekiq can't.I want to ask, is it possible to put
exception_notification
mailers to sidekiq queue? Or maybe it's impossible for now, and I should stop my attempts?Thanks for any advice!