Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/exception_notifier/rake.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
require 'exception_notifier/rake/rails' if defined?(Rails)
require 'exception_notifier/rake/rake'
require 'exception_notifier/rake/rake_patch'
require 'exception_notifier/rake/version'
17 changes: 17 additions & 0 deletions lib/exception_notifier/rake/rails.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Based on/adapted from https://github.com/airbrake/airbrake/blob/master/lib/airbrake/rails.rb

module ExceptionNotifier
class Rake
class Railtie < ::Rails::Railtie
rake_tasks do
# Report exceptions occurring in Rake tasks.
require 'exception_notifier/rake/rake_patch'
# Work around https://github.com/nikhaldi/exception_notification-rake/issues/26
# Rake::TaskManager won't have been defined when rake_patch.rb was first loaded.
if Rails.env.development?
load 'exception_notifier/rake/rake_patch.rb'
end
end
end
end
end
64 changes: 50 additions & 14 deletions lib/exception_notifier/rake/rake_patch.rb
Original file line number Diff line number Diff line change
@@ -1,25 +1,61 @@
# Monkey patching patterns lifted from
# https://github.com/thoughtbot/airbrake/blob/master/lib/airbrake/rake_handler.rb
# Copied/adapted from https://github.com/airbrake/airbrake/blob/master/lib/airbrake/rake.rb

if Rake.const_defined?(:TaskManager)
Rake::TaskManager.record_task_metadata = true
end

module ExceptionNotifier
module RakePatch
def display_error_message(ex)
super(ex)
ExceptionNotifier::Rake.maybe_deliver_notification(ex,
:rake_command_line => reconstruct_command_line)
module RakeTaskPatch
# A wrapper around the original +#execute+, that catches all errors and
# passes them on to ExceptionNotifier.
#
# rubocop:disable Lint/RescueException
def execute(args = nil)
super(args)
rescue Exception => ex
ExceptionNotifier::Rake.maybe_deliver_notification(
ex,
task_info,
)
raise ex
end
# rubocop:enable Lint/RescueException

private

# rubocop:disable Metrics/CyclomaticComplexity, Metrics/AbcSize
def task_info
info = {}

info[:rake_command_line] = reconstruct_command_line
info[:name] = name
info[:timestamp] = timestamp.to_s
info[:investigation] = investigation

info[:full_comment] = full_comment if full_comment
info[:arg_names] = arg_names if arg_names.any?
info[:arg_description] = arg_description if arg_description
info[:locations] = locations if locations.any?
info[:sources] = sources if sources.any?

if prerequisite_tasks.any?
info[:prerequisite_tasks] = prerequisite_tasks.map do |p|
p.__send__(:task_info)
end
end

info
end
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/AbcSize

def reconstruct_command_line
"rake #{ARGV.join(' ')}"
end
end
end

# Only do this if we're actually in a Rake context. In some contexts (e.g.,
# in the Rails console) Rake might not be defined.
if Object.const_defined?(:Rake) && Rake.respond_to?(:application)
Rake.application.instance_eval do
class << self
prepend ExceptionNotifier::RakePatch
end
module Rake
class Task
prepend ExceptionNotifier::RakeTaskPatch
end
end