exception_notification 3.0.1 → 4.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +2 -0
- data/.travis.yml +9 -0
- data/Appraisals +11 -0
- data/CHANGELOG.rdoc +21 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +49 -7
- data/README.md +417 -184
- data/Rakefile +4 -2
- data/examples/sinatra/Gemfile +8 -0
- data/examples/sinatra/Gemfile.lock +95 -0
- data/examples/sinatra/Procfile +2 -0
- data/examples/sinatra/README.md +11 -0
- data/examples/sinatra/config.ru +3 -0
- data/examples/sinatra/sinatra_app.rb +28 -0
- data/exception_notification.gemspec +10 -4
- data/gemfiles/rails3_1.gemfile +7 -0
- data/gemfiles/rails3_2.gemfile +7 -0
- data/gemfiles/rails4_0.gemfile +7 -0
- data/lib/exception_notification.rb +10 -0
- data/lib/exception_notification/rack.rb +45 -0
- data/lib/exception_notification/rails.rb +8 -0
- data/lib/exception_notification/resque.rb +24 -0
- data/lib/exception_notification/sidekiq.rb +22 -0
- data/lib/exception_notifier.rb +89 -61
- data/lib/exception_notifier/campfire_notifier.rb +2 -7
- data/lib/exception_notifier/email_notifier.rb +181 -0
- data/lib/exception_notifier/notifier.rb +9 -178
- data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +3 -1
- data/lib/exception_notifier/views/exception_notifier/_data.html.erb +6 -1
- data/lib/exception_notifier/views/exception_notifier/_environment.html.erb +16 -6
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_request.html.erb +24 -5
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +2 -0
- data/lib/exception_notifier/views/exception_notifier/_session.html.erb +10 -2
- data/lib/exception_notifier/views/exception_notifier/_session.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/_title.html.erb +3 -3
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.html.erb +38 -11
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb +0 -1
- data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +39 -21
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +0 -1
- data/lib/exception_notifier/webhook_notifier.rb +21 -0
- data/lib/generators/exception_notification/install_generator.rb +15 -0
- data/lib/generators/exception_notification/templates/exception_notification.rb +47 -0
- data/test/dummy/Gemfile +2 -1
- data/test/dummy/Gemfile.lock +79 -78
- data/test/dummy/config/environment.rb +9 -7
- data/test/dummy/test/functional/posts_controller_test.rb +22 -37
- data/test/{campfire_test.rb → exception_notifier/campfire_notifier_test.rb} +4 -4
- data/test/exception_notifier/email_notifier_test.rb +144 -0
- data/test/exception_notifier/webhook_notifier_test.rb +41 -0
- data/test/exception_notifier_test.rb +101 -0
- data/test/test_helper.rb +4 -1
- metadata +136 -18
- data/test/background_exception_notification_test.rb +0 -82
- data/test/exception_notification_test.rb +0 -73
data/Rakefile
CHANGED
@@ -1,12 +1,14 @@
|
|
1
|
-
require '
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
2
3
|
Bundler::GemHelper.install_tasks
|
4
|
+
require 'appraisal'
|
3
5
|
|
4
6
|
require 'rake/testtask'
|
5
7
|
|
6
8
|
task 'setup_dummy_app' do
|
7
9
|
unless File.exists? "test/dummy/db/test.sqlite3"
|
8
10
|
Bundler.with_clean_env do
|
9
|
-
sh "cd test/dummy; bundle; rake db:migrate; rake db:test:prepare; cd ../../;"
|
11
|
+
sh "cd test/dummy; bundle; bundle exec rake db:migrate; bundle exec rake db:test:prepare; cd ../../;"
|
10
12
|
end
|
11
13
|
end
|
12
14
|
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
PATH
|
2
|
+
remote: ../../
|
3
|
+
specs:
|
4
|
+
exception_notification (3.0.1)
|
5
|
+
actionmailer (>= 3.0.4)
|
6
|
+
activesupport (>= 3.0.4)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionmailer (3.2.13)
|
12
|
+
actionpack (= 3.2.13)
|
13
|
+
mail (~> 2.5.3)
|
14
|
+
actionpack (3.2.13)
|
15
|
+
activemodel (= 3.2.13)
|
16
|
+
activesupport (= 3.2.13)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
journey (~> 1.0.4)
|
20
|
+
rack (~> 1.4.5)
|
21
|
+
rack-cache (~> 1.2)
|
22
|
+
rack-test (~> 0.6.1)
|
23
|
+
sprockets (~> 2.2.1)
|
24
|
+
activemodel (3.2.13)
|
25
|
+
activesupport (= 3.2.13)
|
26
|
+
builder (~> 3.0.0)
|
27
|
+
activesupport (3.2.13)
|
28
|
+
i18n (= 0.6.1)
|
29
|
+
multi_json (~> 1.0)
|
30
|
+
builder (3.0.4)
|
31
|
+
daemons (1.1.9)
|
32
|
+
erubis (2.7.0)
|
33
|
+
eventmachine (1.0.3)
|
34
|
+
foreman (0.61.0)
|
35
|
+
thor (>= 0.13.6)
|
36
|
+
haml (4.0.2)
|
37
|
+
tilt
|
38
|
+
hike (1.2.1)
|
39
|
+
i18n (0.6.1)
|
40
|
+
journey (1.0.4)
|
41
|
+
mail (2.5.3)
|
42
|
+
i18n (>= 0.4.0)
|
43
|
+
mime-types (~> 1.16)
|
44
|
+
treetop (~> 1.4.8)
|
45
|
+
mailcatcher (0.5.11)
|
46
|
+
activesupport (~> 3.0)
|
47
|
+
eventmachine (~> 1.0.0)
|
48
|
+
haml (>= 3.1, < 5)
|
49
|
+
mail (~> 2.3)
|
50
|
+
sinatra (~> 1.2)
|
51
|
+
skinny (~> 0.2.3)
|
52
|
+
sqlite3 (~> 1.3)
|
53
|
+
thin (~> 1.5.0)
|
54
|
+
mime-types (1.22)
|
55
|
+
multi_json (1.7.2)
|
56
|
+
polyglot (0.3.3)
|
57
|
+
rack (1.4.5)
|
58
|
+
rack-cache (1.2)
|
59
|
+
rack (>= 0.4)
|
60
|
+
rack-protection (1.5.0)
|
61
|
+
rack
|
62
|
+
rack-test (0.6.2)
|
63
|
+
rack (>= 1.0)
|
64
|
+
sinatra (1.3.6)
|
65
|
+
rack (~> 1.4)
|
66
|
+
rack-protection (~> 1.3)
|
67
|
+
tilt (~> 1.3, >= 1.3.3)
|
68
|
+
skinny (0.2.3)
|
69
|
+
eventmachine (~> 1.0.0)
|
70
|
+
thin (~> 1.5.0)
|
71
|
+
sprockets (2.2.2)
|
72
|
+
hike (~> 1.2)
|
73
|
+
multi_json (~> 1.0)
|
74
|
+
rack (~> 1.0)
|
75
|
+
tilt (~> 1.1, != 1.3.0)
|
76
|
+
sqlite3 (1.3.7)
|
77
|
+
thin (1.5.1)
|
78
|
+
daemons (>= 1.0.9)
|
79
|
+
eventmachine (>= 0.12.6)
|
80
|
+
rack (>= 1.0.0)
|
81
|
+
thor (0.18.1)
|
82
|
+
tilt (1.3.6)
|
83
|
+
treetop (1.4.12)
|
84
|
+
polyglot
|
85
|
+
polyglot (>= 0.3.1)
|
86
|
+
|
87
|
+
PLATFORMS
|
88
|
+
ruby
|
89
|
+
|
90
|
+
DEPENDENCIES
|
91
|
+
exception_notification!
|
92
|
+
foreman
|
93
|
+
mailcatcher
|
94
|
+
sinatra (~> 1.3.5)
|
95
|
+
thin (~> 1.5.1)
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Using Exception Notification with Sinatra
|
2
|
+
|
3
|
+
## Quick start
|
4
|
+
|
5
|
+
git clone git@github.com:smartinez87/exception_notification.git
|
6
|
+
cd exception_notification/examples/sinatra
|
7
|
+
bundle install
|
8
|
+
bundle exec foreman start
|
9
|
+
|
10
|
+
|
11
|
+
The last command starts two services, a smtp server and the sinatra app itself. Thus, visit [http://localhost:1080/](http://localhost:1080/) to check the emails sent and, in a separated tab, visit [http://localhost:3000](http://localhost:3000) and cause some errors. For more info, use the [source](https://github.com/smartinez87/exception_notification/blob/master/examples/sinatra/sinatra_app.rb) Luke.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
require 'sinatra/base'
|
4
|
+
require 'exception_notification'
|
5
|
+
|
6
|
+
class SinatraApp < Sinatra::Base
|
7
|
+
use ExceptionNotification::Rack,
|
8
|
+
:email => {
|
9
|
+
:email_prefix => "[Example] ",
|
10
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
11
|
+
:exception_recipients => %w{exceptions@example.com},
|
12
|
+
:smtp_settings => { :address => "localhost", :port => 1025 }
|
13
|
+
}
|
14
|
+
|
15
|
+
get '/' do
|
16
|
+
raise StandardError, "ERROR: #{params[:error]}" unless params[:error].blank?
|
17
|
+
'Everything is fine! Now, lets break things clicking <a href="/?error=ops"> here </a>. Dont forget to see the emails at <a href="http://localhost:1080">mailcatcher</a> !'
|
18
|
+
end
|
19
|
+
|
20
|
+
get '/background_notification' do
|
21
|
+
begin
|
22
|
+
1/0
|
23
|
+
rescue Exception => e
|
24
|
+
ExceptionNotifier.notify_exception(e, :data => {:msg => "Cannot divide by zero!"})
|
25
|
+
end
|
26
|
+
'Check email at <a href="http://localhost:1080">mailcatcher</a>.'
|
27
|
+
end
|
28
|
+
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'exception_notification'
|
3
|
-
s.version = '
|
3
|
+
s.version = '4.0.0.rc1'
|
4
4
|
s.authors = ["Jamis Buck", "Josh Peek"]
|
5
|
-
s.date = %q{2013-
|
5
|
+
s.date = %q{2013-06-20}
|
6
6
|
s.summary = "Exception notification for Rails apps"
|
7
7
|
s.homepage = "http://smartinez87.github.com/exception_notification"
|
8
8
|
s.email = "smartinez87@gmail.com"
|
@@ -12,9 +12,15 @@ Gem::Specification.new do |s|
|
|
12
12
|
s.require_path = 'lib'
|
13
13
|
|
14
14
|
s.add_dependency("actionmailer", ">= 3.0.4")
|
15
|
+
s.add_dependency("activesupport", ">= 3.0.4")
|
15
16
|
|
16
|
-
s.add_development_dependency "tinder", "~> 1.8"
|
17
17
|
s.add_development_dependency "rails", ">= 3.0.4"
|
18
|
-
s.add_development_dependency "
|
18
|
+
s.add_development_dependency "resque", "~> 1.2.0"
|
19
|
+
s.add_development_dependency "sidekiq", "~> 2.0"
|
20
|
+
s.add_development_dependency "tinder", "~> 1.8"
|
21
|
+
s.add_development_dependency "httparty", "~> 0.10.2"
|
22
|
+
s.add_development_dependency "mocha", ">= 0.13.0"
|
19
23
|
s.add_development_dependency "sqlite3", ">= 1.3.4"
|
24
|
+
s.add_development_dependency "coveralls", "~> 0.6.5"
|
25
|
+
s.add_development_dependency "appraisal", ">= 0"
|
20
26
|
end
|
@@ -1 +1,11 @@
|
|
1
1
|
require 'exception_notifier'
|
2
|
+
require 'exception_notification/rack'
|
3
|
+
|
4
|
+
module ExceptionNotification
|
5
|
+
# Alternative way to setup ExceptionNotification.
|
6
|
+
# Run 'rails generate exception_notification:install' to create
|
7
|
+
# a fresh initializer with all configuration values.
|
8
|
+
def self.configure
|
9
|
+
yield ExceptionNotifier
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ExceptionNotification
|
2
|
+
class Rack
|
3
|
+
def initialize(app, options = {})
|
4
|
+
@app = app
|
5
|
+
|
6
|
+
ExceptionNotifier.ignored_exceptions = options.delete(:ignore_exceptions) if options.key?(:ignore_exceptions)
|
7
|
+
|
8
|
+
if options.key?(:ignore_if)
|
9
|
+
rack_ignore = options.delete(:ignore_if)
|
10
|
+
ExceptionNotifier.ignore_if do |exception, options|
|
11
|
+
options.key?(:env) && rack_ignore.call(options[:env], exception)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
if options.key?(:ignore_crawlers)
|
16
|
+
ignore_crawlers = options.delete(:ignore_crawlers)
|
17
|
+
ExceptionNotifier.ignore_if do |exception, options|
|
18
|
+
options.key?(:env) && from_crawler(options[:env], ignore_crawlers)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
options.each do |notifier_name, options|
|
23
|
+
ExceptionNotifier.register_exception_notifier(notifier_name, options)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def call(env)
|
28
|
+
@app.call(env)
|
29
|
+
rescue Exception => exception
|
30
|
+
if ExceptionNotifier.notify_exception(exception, :env => env)
|
31
|
+
env['exception_notifier.delivered'] = true
|
32
|
+
end
|
33
|
+
raise exception
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def from_crawler(env, ignored_crawlers)
|
39
|
+
agent = env['HTTP_USER_AGENT']
|
40
|
+
Array(ignored_crawlers).any? do |crawler|
|
41
|
+
agent =~ Regexp.new(crawler)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'resque/failure/base'
|
2
|
+
|
3
|
+
module ExceptionNotification
|
4
|
+
class Resque < Resque::Failure::Base
|
5
|
+
|
6
|
+
def self.count
|
7
|
+
Stat[:failed]
|
8
|
+
end
|
9
|
+
|
10
|
+
def save
|
11
|
+
data = {
|
12
|
+
:failed_at => Time.now.to_s,
|
13
|
+
:queue => queue,
|
14
|
+
:worker => worker.to_s,
|
15
|
+
:payload => payload,
|
16
|
+
:error_class => exception.class.name,
|
17
|
+
:error_message => exception.message
|
18
|
+
}
|
19
|
+
|
20
|
+
ExceptionNotifier.notify_exception(exception, :data => { :resque => data })
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'sidekiq'
|
2
|
+
|
3
|
+
module ExceptionNotification
|
4
|
+
class Sidekiq
|
5
|
+
|
6
|
+
def call(worker, msg, queue)
|
7
|
+
begin
|
8
|
+
yield
|
9
|
+
rescue Exception => exception
|
10
|
+
ExceptionNotifier.notify_exception(exception, :data => { :sidekiq => msg })
|
11
|
+
raise exception
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
::Sidekiq.configure_server do |config|
|
19
|
+
config.server_middleware do |chain|
|
20
|
+
chain.add ::ExceptionNotification::Sidekiq
|
21
|
+
end
|
22
|
+
end
|
data/lib/exception_notifier.rb
CHANGED
@@ -1,75 +1,103 @@
|
|
1
|
-
require '
|
2
|
-
require '
|
3
|
-
require 'exception_notifier/campfire_notifier'
|
1
|
+
require 'logger'
|
2
|
+
require 'active_support/core_ext/string/inflections'
|
4
3
|
|
5
|
-
|
4
|
+
module ExceptionNotifier
|
6
5
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
6
|
+
autoload :Notifier, 'exception_notifier/notifier'
|
7
|
+
autoload :EmailNotifier, 'exception_notifier/email_notifier'
|
8
|
+
autoload :CampfireNotifier, 'exception_notifier/campfire_notifier'
|
9
|
+
autoload :WebhookNotifier, 'exception_notifier/webhook_notifier'
|
10
|
+
|
11
|
+
class UndefinedNotifierError < StandardError; end
|
12
|
+
|
13
|
+
# Define logger
|
14
|
+
mattr_accessor :logger
|
15
|
+
@@logger = Logger.new(STDOUT)
|
16
|
+
|
17
|
+
# Define a set of exceptions to be ignored, ie, dont send notifications when any of them are raised.
|
18
|
+
mattr_accessor :ignored_exceptions
|
19
|
+
@@ignored_exceptions = %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError}
|
20
|
+
|
21
|
+
class << self
|
22
|
+
# Store conditions that decide when exceptions must be ignored or not.
|
23
|
+
@@ignores = []
|
24
|
+
|
25
|
+
# Store notifiers that send notifications when exceptions are raised.
|
26
|
+
@@notifiers = {}
|
27
|
+
|
28
|
+
def notify_exception(exception, options={})
|
29
|
+
return false if ignored_exception?(options[:ignore_exceptions], exception)
|
30
|
+
return false if ignored?(exception, options)
|
31
|
+
selected_notifiers = options.delete(:notifiers) || notifiers
|
32
|
+
[*selected_notifiers].each do |notifier|
|
33
|
+
fire_notification(notifier, exception, options.dup)
|
34
|
+
end
|
35
|
+
true
|
12
36
|
end
|
13
|
-
end
|
14
37
|
|
15
|
-
|
16
|
-
|
17
|
-
|
38
|
+
def register_exception_notifier(name, notifier_or_options)
|
39
|
+
if notifier_or_options.respond_to?(:call)
|
40
|
+
@@notifiers[name] = notifier_or_options
|
41
|
+
elsif notifier_or_options.is_a?(Hash)
|
42
|
+
create_and_register_notifier(name, notifier_or_options)
|
43
|
+
else
|
44
|
+
raise ArgumentError, "Invalid notifier '#{name}' defined as #{notifier_or_options.inspect}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
alias add_notifier register_exception_notifier
|
18
48
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
Notifier.default_sender_address = @options[:sender_address]
|
23
|
-
Notifier.default_exception_recipients = @options[:exception_recipients]
|
24
|
-
Notifier.default_email_prefix = @options[:email_prefix]
|
25
|
-
Notifier.default_email_format = @options[:email_format]
|
26
|
-
Notifier.default_sections = @options[:sections]
|
27
|
-
Notifier.default_background_sections = @options[:background_sections]
|
28
|
-
Notifier.default_verbose_subject = @options[:verbose_subject]
|
29
|
-
Notifier.default_normalize_subject = @options[:normalize_subject]
|
30
|
-
Notifier.default_smtp_settings = @options[:smtp_settings]
|
31
|
-
Notifier.default_email_headers = @options[:email_headers]
|
32
|
-
|
33
|
-
@campfire = CampfireNotifier.new @options[:campfire]
|
34
|
-
|
35
|
-
@options[:ignore_exceptions] ||= self.class.default_ignore_exceptions
|
36
|
-
@options[:ignore_crawlers] ||= self.class.default_ignore_crawlers
|
37
|
-
@options[:ignore_if] ||= lambda { |env, e| false }
|
38
|
-
end
|
49
|
+
def unregister_exception_notifier(name)
|
50
|
+
@@notifiers.delete(name)
|
51
|
+
end
|
39
52
|
|
40
|
-
|
41
|
-
|
42
|
-
rescue Exception => exception
|
43
|
-
options = (env['exception_notifier.options'] ||= Notifier.default_options)
|
44
|
-
options.reverse_merge!(@options)
|
45
|
-
|
46
|
-
unless ignored_exception(options[:ignore_exceptions], exception) ||
|
47
|
-
from_crawler(options[:ignore_crawlers], env['HTTP_USER_AGENT']) ||
|
48
|
-
conditionally_ignored(options[:ignore_if], env, exception)
|
49
|
-
Notifier.exception_notification(env, exception).deliver
|
50
|
-
@campfire.exception_notification(exception)
|
51
|
-
env['exception_notifier.delivered'] = true
|
53
|
+
def registered_exception_notifier(name)
|
54
|
+
@@notifiers[name]
|
52
55
|
end
|
53
56
|
|
54
|
-
|
55
|
-
|
57
|
+
def notifiers
|
58
|
+
@@notifiers.keys
|
59
|
+
end
|
56
60
|
|
57
|
-
|
61
|
+
# Adds a condition to decide when an exception must be ignored or not.
|
62
|
+
#
|
63
|
+
# ExceptionNotifier.ignore_if do |exception, options|
|
64
|
+
# not Rails.env.production?
|
65
|
+
# end
|
66
|
+
def ignore_if(&block)
|
67
|
+
@@ignores << block
|
68
|
+
end
|
58
69
|
|
59
|
-
|
60
|
-
|
61
|
-
|
70
|
+
def clear_ignore_conditions!
|
71
|
+
@@ignores.clear
|
72
|
+
end
|
62
73
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
74
|
+
private
|
75
|
+
def ignored?(exception, options)
|
76
|
+
@@ignores.any?{ |condition| condition.call(exception, options) }
|
77
|
+
rescue Exception => e
|
78
|
+
logger.warn "An error occurred when evaluating an ignore condition. #{e.class}: #{e.message}"
|
79
|
+
false
|
80
|
+
end
|
69
81
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
82
|
+
def ignored_exception?(ignore_array, exception)
|
83
|
+
(Array(ignored_exceptions) + Array(ignore_array)).map(&:to_s).include?(exception.class.name)
|
84
|
+
end
|
85
|
+
|
86
|
+
def fire_notification(notifier_name, exception, options)
|
87
|
+
notifier = registered_exception_notifier(notifier_name)
|
88
|
+
notifier.call(exception, options)
|
89
|
+
rescue Exception => e
|
90
|
+
logger.warn "An error occurred when sending a notification using '#{notifier_name}' notifier. #{e.class}: #{e.message}"
|
91
|
+
false
|
92
|
+
end
|
93
|
+
|
94
|
+
def create_and_register_notifier(name, options)
|
95
|
+
notifier_classname = "#{name}_notifier".camelize
|
96
|
+
notifier_class = ExceptionNotifier.const_get(notifier_classname)
|
97
|
+
notifier = notifier_class.new(options)
|
98
|
+
register_exception_notifier(name, notifier)
|
99
|
+
rescue NameError => e
|
100
|
+
raise UndefinedNotifierError, "No notifier named '#{name}' was found. Please, revise your configuration options. Cause: #{e.message}"
|
101
|
+
end
|
74
102
|
end
|
75
103
|
end
|