How to catch errors and send them to Bugsnag when using `rails runner`?

bugsnag, ruby, ruby-on-rails, ruby-on-rails-3, ruby-on-rails-4

Solution

Rails runner is very difficult to configure or to customize. That is because all it really is, is a script with this main body:

if code_or_file.nil?
  $stderr.puts "Run '#{$0} -h' for help."
  exit 1
elsif File.exist?(code_or_file)
  $0 = code_or_file
  Kernel.load code_or_file
else
  eval(code_or_file, binding, __FILE__, __LINE__)
end

As you can see, it just does an `eval` of the code you sent, so there's no wrapper, no class you can extend, and basically nothing you can configure. It is better to create a rake task to perform things the same way as runner, but this time in an environment that will be controlled by Rake, therefore allowing you to configure everything you need:

desc 'Wraps a runner command with rake'
task :runner, [:command] => :environment do |t, args|
  eval(args[:command])
end

Then, you call it using

rake 'runner["MyTask.run"]'

This will run the tasks in a very similar way to using `rails runner`, but in the context of rake (which will include using Bugsnag).

Problem

We're running several cron tasks in our server, and we start them all using rails runner, like this: ``` rails runner 'MyTask.run' ``` where `MyTask` is a class in the project. The thing is, we use Bugsnag to handle errors in case anything fails. When we run a rake task, Bugsnag saves the errors and lists them in their website. But this does not happen when using `rails runner`. How can I configure rails to send errors to Bugsnag when this happens?

Original source