exception_notification 4.0.1 → 4.1.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (28) hide show
  1. data/CHANGELOG.rdoc +10 -0
  2. data/Gemfile.lock +18 -14
  3. data/README.md +109 -9
  4. data/exception_notification.gemspec +5 -3
  5. data/lib/exception_notification/sidekiq.rb +12 -3
  6. data/lib/exception_notifier.rb +2 -1
  7. data/lib/exception_notifier/email_notifier.rb +3 -1
  8. data/lib/exception_notifier/hipchat_notifier.rb +7 -4
  9. data/lib/exception_notifier/irc_notifier.rb +45 -0
  10. data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
  11. data/lib/exception_notifier/views/exception_notifier/_data.html.erb +1 -1
  12. data/lib/exception_notifier/views/exception_notifier/_request.html.erb +9 -9
  13. data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
  14. data/lib/exception_notifier/views/exception_notifier/_session.html.erb +2 -2
  15. data/lib/exception_notifier/views/exception_notifier/_session.text.erb +1 -1
  16. data/lib/exception_notifier/views/exception_notifier/_title.html.erb +1 -1
  17. data/lib/exception_notifier/views/exception_notifier/background_exception_notification.html.erb +3 -3
  18. data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
  19. data/lib/exception_notifier/webhook_notifier.rb +4 -2
  20. data/test/dummy/Gemfile.lock +1 -1
  21. data/test/exception_notifier/hipchat_notifier_test.rb +14 -0
  22. data/test/exception_notifier/irc_notifier_test.rb +85 -0
  23. data/test/exception_notifier/sidekiq_test.rb +27 -0
  24. data/test/exception_notifier_test.rb +1 -1
  25. metadata +26 -8
  26. data/.gemtest +0 -0
  27. data/.gitignore +0 -2
  28. data/.travis.yml +0 -9
data/CHANGELOG.rdoc CHANGED
@@ -1,3 +1,13 @@
1
+ == unreleased
2
+
3
+ * enhancements
4
+ * Add support for Sidekiq 3.0 (by @mbrictson)
5
+ * Add IRC notifier (by @nathanjsharpe)
6
+ * Add ActionController::UnknownFormat to default ignored exceptions (by @rezwyi)
7
+ * Add message_template option to HipChat notifier (by @makimoto)
8
+
9
+ * bug fixes
10
+ * Fix `Rails.root` exception (by @hovatterz)
1
11
  == 4.0.1
2
12
 
3
13
  * enhancements
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- exception_notification (4.0.1)
4
+ exception_notification (4.1.0.rc1)
5
5
  actionmailer (>= 3.0.4)
6
6
  activesupport (>= 3.0.4)
7
7
 
@@ -35,15 +35,18 @@ GEM
35
35
  activesupport (3.2.6)
36
36
  i18n (~> 0.6)
37
37
  multi_json (~> 1.0)
38
+ addressable (2.3.5)
38
39
  appraisal (0.5.2)
39
40
  bundler
40
41
  rake
41
42
  arel (3.0.2)
42
43
  builder (3.0.0)
43
- celluloid (0.14.0)
44
- timers (>= 1.0.0)
44
+ carrier-pigeon (0.7.0)
45
+ addressable
46
+ celluloid (0.15.2)
47
+ timers (~> 1.1.0)
45
48
  colorize (0.5.8)
46
- connection_pool (1.0.0)
49
+ connection_pool (2.0.0)
47
50
  coveralls (0.6.5)
48
51
  colorize
49
52
  multi_json (~> 1.3)
@@ -66,7 +69,7 @@ GEM
66
69
  multi_xml (>= 0.5.2)
67
70
  i18n (0.6.0)
68
71
  journey (1.0.4)
69
- json (1.7.3)
72
+ json (1.8.1)
70
73
  mail (2.4.4)
71
74
  i18n (>= 0.4.0)
72
75
  mime-types (~> 1.16)
@@ -104,20 +107,20 @@ GEM
104
107
  rake (0.9.2.2)
105
108
  rdoc (3.12)
106
109
  json (~> 1.4)
107
- redis (3.0.4)
108
- redis-namespace (1.3.0)
109
- redis (~> 3.0.0)
110
+ redis (3.0.7)
111
+ redis-namespace (1.4.1)
112
+ redis (~> 3.0.4)
110
113
  resque (1.2.3)
111
114
  redis
112
115
  redis-namespace
113
116
  rest-client (1.6.7)
114
117
  mime-types (>= 1.16)
115
- sidekiq (2.12.0)
116
- celluloid (>= 0.14.0)
117
- connection_pool (>= 1.0.0)
118
+ sidekiq (3.0.0)
119
+ celluloid (>= 0.15.2)
120
+ connection_pool (>= 2.0.0)
118
121
  json
119
- redis (>= 3.0)
120
- redis-namespace
122
+ redis (>= 3.0.6)
123
+ redis-namespace (>= 1.3.1)
121
124
  simple_oauth (0.1.9)
122
125
  simplecov (0.7.1)
123
126
  multi_json (~> 1.0)
@@ -155,6 +158,7 @@ PLATFORMS
155
158
 
156
159
  DEPENDENCIES
157
160
  appraisal
161
+ carrier-pigeon (>= 0.7.0)
158
162
  coveralls (~> 0.6.5)
159
163
  exception_notification!
160
164
  hipchat (>= 0.11.0)
@@ -162,6 +166,6 @@ DEPENDENCIES
162
166
  mocha (>= 0.13.0)
163
167
  rails (>= 3.0.4)
164
168
  resque (~> 1.2.0)
165
- sidekiq (~> 2.0)
169
+ sidekiq (~> 3.0)
166
170
  sqlite3 (>= 1.3.4)
167
171
  tinder (~> 1.8)
data/README.md CHANGED
@@ -266,6 +266,8 @@ Whatever::Application.config.middleware.use ExceptionNotification::Rack,
266
266
  }
267
267
  ```
268
268
 
269
+ A complete list of `smtp_settings` options can be found in the [ActionMailer Configuration documentation](http://api.rubyonrails.org/classes/ActionMailer/Base.html#class-ActionMailer::Base-label-Configuration+options).
270
+
269
271
 
270
272
  ##### mailer_parent
271
273
 
@@ -367,21 +369,21 @@ The HipChat room where the notifications must be published to.
367
369
 
368
370
  The API token to allow access to your HipChat account.
369
371
 
370
- ##### announce
372
+ ##### notify
371
373
 
372
- *Boolean, optionnal*
374
+ *Boolean, optional*
373
375
 
374
376
  Notify users. Default : false.
375
377
 
376
378
  ##### color
377
379
 
378
- *String, optionnal*
380
+ *String, optional*
379
381
 
380
382
  Color of the message. Default : 'red'.
381
383
 
382
384
  ##### from
383
385
 
384
- *String, optionnal*
386
+ *String, optional, maximum length : 15*
385
387
 
386
388
  Message will appear from this nickname. Default : 'Exception'.
387
389
 
@@ -448,6 +450,104 @@ Whatever::Application.config.middleware.use ExceptionNotification::Rack,
448
450
 
449
451
  For more HTTParty options, check out the [documentation](https://github.com/jnunemaker/httparty).
450
452
 
453
+ ### IRC notifier
454
+
455
+ This notifier sends notifications to an IRC channel using the carrier-pigeon gem.
456
+
457
+ #### Usage
458
+
459
+ Just add the [carrier-pigeon](https://github.com/portertech/carrier-pigeon) gem to your `Gemfile`:
460
+
461
+ ```ruby
462
+ gem 'carrier-pigeon'
463
+ ```
464
+
465
+ To configure it, you need to set at least the 'domain' option, like this:
466
+
467
+ ```ruby
468
+ Whatever::Application.config.middleware.use ExceptionNotification::Rack,
469
+ :email => {
470
+ :email_prefix => "[Whatever] ",
471
+ :sender_address => %{"notifier" <notifier@example.com>},
472
+ :exception_recipients => %w{exceptions@example.com}
473
+ },
474
+ :irc => {
475
+ :domain => 'irc.example.com'
476
+ }
477
+ ```
478
+
479
+ There are several other options, which are described below. For example, to use ssl and a password, add a prefix, post to the '#log' channel, and include recipients in the message (so that they will be notified), your configuration might look like this:
480
+
481
+ ```ruby
482
+ Whatever::Application.config.middleware.use ExceptionNotification::Rack,
483
+ :irc => {
484
+ :domain => 'irc.example.com',
485
+ :nick => 'BadNewsBot',
486
+ :password => 'secret',
487
+ :port => 6697,
488
+ :channel => '#log',
489
+ :ssl => true,
490
+ :prefix => '[Exception Notification]',
491
+ :recipients => ['peter', 'michael', 'samir']
492
+ }
493
+
494
+ ```
495
+
496
+ #### Options
497
+
498
+ ##### domain
499
+
500
+ *String, required*
501
+
502
+ The domain name of your IRC server.
503
+
504
+ ##### nick
505
+
506
+ *String, optional*
507
+
508
+ The message will appear from this nick. Default : 'ExceptionNotifierBot'.
509
+
510
+ ##### password
511
+
512
+ *String, optional*
513
+
514
+ Password for your IRC server.
515
+
516
+ ##### port
517
+
518
+ *String, optional*
519
+
520
+ Port your IRC server is listening on. Default : 6667.
521
+
522
+ ##### channel
523
+
524
+ *String, optional*
525
+
526
+ Message will appear in this channel. Default : '#log'.
527
+
528
+ ##### notice
529
+
530
+ *Boolean, optional*
531
+
532
+ Send a notice. Default : false.
533
+
534
+ ##### ssl
535
+
536
+ *Boolean, optional*
537
+
538
+ Whether to use SSL. Default : false.
539
+
540
+ ##### join
541
+
542
+ *Boolean, optional*
543
+
544
+ Join a channel. Default : false.
545
+
546
+ ##### recipients
547
+
548
+ *Array of strings, optional*
549
+
550
+ Nicks to include in the message. Default: []
451
551
 
452
552
  ### Custom notifier
453
553
 
@@ -506,7 +606,7 @@ You can choose to ignore certain exceptions, which will make ExceptionNotificati
506
606
 
507
607
  ### :ignore_exceptions
508
608
 
509
- *Array of strings, default: %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError}*
609
+ *Array of strings, default: %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat}*
510
610
 
511
611
  Ignore specified exception types. To achieve that, you should use the `:ignore_exceptions` option, like this:
512
612
 
@@ -620,6 +720,10 @@ or
620
720
 
621
721
  ## Versions
622
722
 
723
+ For v4.0.1, see this tag:
724
+
725
+ http://github.com/smartinez87/exception_notification/tree/v4.0.1
726
+
623
727
  For v4.0.0, see this tag:
624
728
 
625
729
  http://github.com/smartinez87/exception_notification/tree/v4.0.0
@@ -632,10 +736,6 @@ For v3.0.0, see this tag:
632
736
 
633
737
  http://github.com/smartinez87/exception_notification/tree/v3.0.0
634
738
 
635
- For v2.6.1, see this tag:
636
-
637
- http://github.com/smartinez87/exception_notification/tree/v2.6.1
638
-
639
739
  For previous releases, visit:
640
740
 
641
741
  https://github.com/smartinez87/exception_notification/tags
@@ -1,8 +1,8 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'exception_notification'
3
- s.version = '4.0.1'
3
+ s.version = '4.1.0.rc1'
4
4
  s.authors = ["Jamis Buck", "Josh Peek"]
5
- s.date = %q{2013-09-15}
5
+ s.date = %q{2014-04-16}
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,6 +12,7 @@ Gem::Specification.new do |s|
12
12
  s.required_rubygems_version = '>= 1.8.11'
13
13
 
14
14
  s.files = `git ls-files`.split("\n")
15
+ s.files -= `git ls-files -- .??*`.split("\n")
15
16
  s.test_files = `git ls-files -- test`.split("\n")
16
17
  s.require_path = 'lib'
17
18
 
@@ -20,7 +21,7 @@ Gem::Specification.new do |s|
20
21
 
21
22
  s.add_development_dependency "rails", ">= 3.0.4"
22
23
  s.add_development_dependency "resque", "~> 1.2.0"
23
- s.add_development_dependency "sidekiq", "~> 2.0"
24
+ s.add_development_dependency "sidekiq", "~> 3.0"
24
25
  s.add_development_dependency "tinder", "~> 1.8"
25
26
  s.add_development_dependency "httparty", "~> 0.10.2"
26
27
  s.add_development_dependency "mocha", ">= 0.13.0"
@@ -28,4 +29,5 @@ Gem::Specification.new do |s|
28
29
  s.add_development_dependency "coveralls", "~> 0.6.5"
29
30
  s.add_development_dependency "appraisal", ">= 0"
30
31
  s.add_development_dependency "hipchat", ">= 0.11.0"
32
+ s.add_development_dependency "carrier-pigeon", ">= 0.7.0"
31
33
  end
@@ -1,5 +1,6 @@
1
1
  require 'sidekiq'
2
2
 
3
+ # Note: this class is only needed for Sidekiq version < 3.
3
4
  module ExceptionNotification
4
5
  class Sidekiq
5
6
 
@@ -15,8 +16,16 @@ module ExceptionNotification
15
16
  end
16
17
  end
17
18
 
18
- ::Sidekiq.configure_server do |config|
19
- config.server_middleware do |chain|
20
- chain.add ::ExceptionNotification::Sidekiq
19
+ if ::Sidekiq::VERSION < '3'
20
+ ::Sidekiq.configure_server do |config|
21
+ config.server_middleware do |chain|
22
+ chain.add ::ExceptionNotification::Sidekiq
23
+ end
24
+ end
25
+ else
26
+ ::Sidekiq.configure_server do |config|
27
+ config.error_handlers << Proc.new { |ex, context|
28
+ ExceptionNotifier.notify_exception(ex, :data => { :sidekiq => context })
29
+ }
21
30
  end
22
31
  end
@@ -9,6 +9,7 @@ module ExceptionNotifier
9
9
  autoload :CampfireNotifier, 'exception_notifier/campfire_notifier'
10
10
  autoload :HipchatNotifier, 'exception_notifier/hipchat_notifier'
11
11
  autoload :WebhookNotifier, 'exception_notifier/webhook_notifier'
12
+ autoload :IrcNotifier, 'exception_notifier/irc_notifier'
12
13
 
13
14
  class UndefinedNotifierError < StandardError; end
14
15
 
@@ -18,7 +19,7 @@ module ExceptionNotifier
18
19
 
19
20
  # Define a set of exceptions to be ignored, ie, dont send notifications when any of them are raised.
20
21
  mattr_accessor :ignored_exceptions
21
- @@ignored_exceptions = %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError}
22
+ @@ignored_exceptions = %w{ActiveRecord::RecordNotFound AbstractController::ActionNotFound ActionController::RoutingError ActionController::UnknownFormat}
22
23
 
23
24
  class << self
24
25
  # Store conditions that decide when exceptions must be ignored or not.
@@ -111,7 +111,9 @@ module ExceptionNotifier
111
111
  end
112
112
 
113
113
  def load_custom_views
114
- self.prepend_view_path Rails.root.nil? ? "app/views" : "#{Rails.root}/app/views" if defined?(Rails)
114
+ if defined?(Rails) && Rails.respond_to?(:root)
115
+ self.prepend_view_path Rails.root.nil? ? "app/views" : "#{Rails.root}/app/views"
116
+ end
115
117
  end
116
118
  end
117
119
  end
@@ -7,10 +7,13 @@ module ExceptionNotifier
7
7
 
8
8
  def initialize(options)
9
9
  begin
10
- api_token = options.delete(:api_token)
11
- room_name = options.delete(:room_name)
10
+ api_token = options.delete(:api_token)
11
+ room_name = options.delete(:room_name)
12
12
  @from = options.delete(:from) || 'Exception'
13
- @room = HipChat::Client.new(api_token)[room_name]
13
+ @room = HipChat::Client.new(api_token)[room_name]
14
+ @message_template = options.delete(:message_template) || ->(exception) {
15
+ "A new exception occurred: '#{exception.message}' on '#{exception.backtrace.first}'"
16
+ }
14
17
  @message_options = options
15
18
  @message_options[:color] ||= 'red'
16
19
  rescue
@@ -21,7 +24,7 @@ module ExceptionNotifier
21
24
  def call(exception, options={})
22
25
  return if !active?
23
26
 
24
- message = "A new exception occurred: '#{exception.message}' on '#{exception.backtrace.first}'"
27
+ message = @message_template.call(exception)
25
28
  @room.send(@from, message, @message_options)
26
29
  end
27
30
 
@@ -0,0 +1,45 @@
1
+ module ExceptionNotifier
2
+ class IrcNotifier
3
+ def initialize(options)
4
+ @config = OpenStruct.new
5
+ parse_options(options)
6
+ end
7
+
8
+ def call(exception, options={})
9
+ message = "'#{exception.message}' on '#{exception.backtrace.first}'"
10
+ send_message([*@config.prefix, *message].join(' ')) if active?
11
+ end
12
+
13
+ def send_message(message)
14
+ CarrierPigeon.send @config.irc.merge({message: message})
15
+ end
16
+
17
+ private
18
+ def parse_options(options)
19
+ nick = options.fetch(:nick, 'ExceptionNotifierBot')
20
+ password = options[:password] ? ":#{options[:password]}" : nil
21
+ domain = options.fetch(:domain, nil)
22
+ port = options[:port] ? ":#{options[:port]}" : nil
23
+ channel = options.fetch(:channel, '#log')
24
+ notice = options.fetch(:notice, false)
25
+ ssl = options.fetch(:ssl, false)
26
+ join = options.fetch(:join, false)
27
+ uri = "irc://#{nick}#{password}@#{domain}#{port}/#{channel}"
28
+ prefix = options.fetch(:prefix, nil)
29
+ recipients = options[:recipients] ? options[:recipients].join(', ') + ':' : nil
30
+
31
+ @config.prefix = [*prefix, *recipients].join(' ')
32
+ @config.irc = { uri: uri, ssl: ssl, notice: notice, join: join }
33
+ end
34
+
35
+ def active?
36
+ valid_uri? @config.irc[:uri]
37
+ end
38
+
39
+ def valid_uri?(uri)
40
+ !!URI.parse(uri)
41
+ rescue URI::InvalidURIError
42
+ false
43
+ end
44
+ end
45
+ end
@@ -1,3 +1,3 @@
1
1
  <pre style="font-size: 12px; padding: 10px; border: 1px solid #e1e1e8; background-color:#f5f5f5">
2
- <%= raw @backtrace.join("\n") %>
2
+ <%= @backtrace.join("\n") %>
3
3
  </pre>
@@ -1,6 +1,6 @@
1
1
  <ul style="list-style: none">
2
2
  <li>
3
3
  <strong>data:</strong>
4
- <span><%= raw PP.pp(@data, "") %></span>
4
+ <span><%= PP.pp(@data, "") %></span>
5
5
  </li>
6
6
  </ul>
@@ -1,36 +1,36 @@
1
1
  <ul style="list-style: none">
2
2
  <li>
3
3
  <strong>URL:</strong>
4
- <span><%= raw @request.url %></span>
4
+ <span><%= @request.url %></span>
5
5
  </li>
6
6
  <li>
7
7
  <strong>HTTP Method:</strong>
8
- <span><%= raw @request.request_method %></span>
8
+ <span><%= @request.request_method %></span>
9
9
  </li>
10
10
  <li>
11
11
  <strong>IP Address:</strong>
12
- <span><%= raw @request.remote_ip %></span>
12
+ <span><%= @request.remote_ip %></span>
13
13
  </li>
14
14
  <li>
15
15
  <strong>Parameters:</strong>
16
- <span><%= raw @request.filtered_parameters.inspect %></span>
16
+ <span><%= @request.filtered_parameters.inspect %></span>
17
17
  </li>
18
18
  <li>
19
19
  <strong>Timestamp:</strong>
20
- <span><%= raw Time.current %></span>
20
+ <span><%= Time.current %></span>
21
21
  </li>
22
22
  <li>
23
23
  <strong>Server:</strong>
24
- <span><%= raw Socket.gethostname %></span>
24
+ <span><%= Socket.gethostname %></span>
25
25
  </li>
26
- <% if defined?(Rails) %>
26
+ <% if defined?(Rails) && Rails.respond_to?(:root) %>
27
27
  <li>
28
28
  <strong>Rails root:</strong>
29
- <span><%= raw Rails.root %></span>
29
+ <span><%= Rails.root %></span>
30
30
  </li>
31
31
  <% end %>
32
32
  <li>
33
33
  <strong>Process:</strong>
34
- <span><%= raw $$ %></span>
34
+ <span><%= $$ %></span>
35
35
  </li>
36
36
  </ul>
@@ -4,7 +4,7 @@
4
4
  * Parameters : <%= raw @request.filtered_parameters.inspect %>
5
5
  * Timestamp : <%= raw Time.current %>
6
6
  * Server : <%= raw Socket.gethostname %>
7
- <% if defined?(Rails) %>
7
+ <% if defined?(Rails) && Rails.respond_to?(:root) %>
8
8
  * Rails root : <%= raw Rails.root %>
9
9
  <% end %>
10
10
  * Process: <%= raw $$ %>
@@ -1,10 +1,10 @@
1
1
  <ul style="list-style: none">
2
2
  <li>
3
3
  <strong>session_id: </strong>
4
- <span><%= @request.ssl? ? "[FILTERED]" : (raw (@request.session['session_id'] || (@request.env["rack.session.options"] and @request.env["rack.session.options"][:id])).inspect.html_safe) %></span>
4
+ <span><%= @request.ssl? ? "[FILTERED]" : (@request.session['session_id'] || (@request.env["rack.session.options"] and @request.env["rack.session.options"][:id]).inspect) %></span>
5
5
  </li>
6
6
  <li>
7
7
  <strong>data: </strong>
8
- <span><%= raw PP.pp(@request.session, "") %></span>
8
+ <span><%= PP.pp(@request.session.to_hash, "") %></span>
9
9
  </li>
10
10
  </ul>
@@ -1,2 +1,2 @@
1
1
  * session id: <%= @request.ssl? ? "[FILTERED]" : (raw (@request.session['session_id'] || (@request.env["rack.session.options"] and @request.env["rack.session.options"][:id])).inspect.html_safe) %>
2
- * data: <%= raw PP.pp(@request.session, "") %>
2
+ * data: <%= raw PP.pp(@request.session.to_hash, "") %>
@@ -1,3 +1,3 @@
1
1
  <h2>
2
- <%= raw title.to_s.humanize %>
2
+ <%= title.to_s.humanize %>
3
3
  </h2>
@@ -30,11 +30,11 @@
30
30
  <tr>
31
31
  <td style="padding: 10px; border: 1px solid #eed3d7; background-color: #f2dede">
32
32
  <h3 style="color: #b94a48">
33
- <%= @exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A' %> <%= @exception.class %> occurred in background at <%= raw Time.current %> :
33
+ <%= @exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A' %> <%= @exception.class %> occurred in background at <%= Time.current %> :
34
34
  </h3>
35
- <p style="color: #b94a48"><%= raw @exception.message %></p>
35
+ <p style="color: #b94a48"><%= @exception.message %></p>
36
36
  <pre style="font-size: 12px; padding: 5px; background-color:#f5f5f5">
37
- <%= raw @backtrace.first %>
37
+ <%= @backtrace.first %>
38
38
  </pre>
39
39
  </td>
40
40
  </tr>
@@ -32,9 +32,9 @@
32
32
  <h3 style="color: #b94a48">
33
33
  <%= @exception.class.to_s =~ /^[aeiou]/i ? 'An' : 'A' %> <%= @exception.class %> occurred in <%= @kontroller.controller_name %>#<%= @kontroller.action_name %>:
34
34
  </h3>
35
- <p style="color: #b94a48"><%= raw @exception.message %></p>
35
+ <p style="color: #b94a48"><%= @exception.message %></p>
36
36
  <pre style="font-size: 12px; padding: 5px; background-color:#f5f5f5">
37
- <%= raw @backtrace.first %>
37
+ <%= @backtrace.first %>
38
38
  </pre>
39
39
  </td>
40
40
  </tr>
@@ -17,7 +17,9 @@ module ExceptionNotifier
17
17
  options[:body] ||= {}
18
18
  options[:body][:server] = Socket.gethostname
19
19
  options[:body][:process] = $$
20
- options[:body][:rails_root] = Rails.root if defined?(Rails)
20
+ if defined?(Rails) && Rails.respond_to?(:root)
21
+ options[:body][:rails_root] = Rails.root
22
+ end
21
23
  options[:body][:exception] = {:error_class => exception.class.to_s,
22
24
  :message => exception.message.inspect,
23
25
  :backtrace => exception.backtrace}
@@ -27,7 +29,7 @@ module ExceptionNotifier
27
29
  request = ActionDispatch::Request.new(env)
28
30
 
29
31
  request_items = {:url => request.original_url,
30
- :http_method => request.http_method,
32
+ :http_method => request.method,
31
33
  :ip_address => request.remote_ip,
32
34
  :parameters => request.filtered_parameters,
33
35
  :timestamp => Time.current }
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: ../../..
3
3
  specs:
4
- exception_notification (4.0.0)
4
+ exception_notification (4.0.1)
5
5
  actionmailer (>= 3.0.4)
6
6
  activesupport (>= 3.0.4)
7
7
 
@@ -59,6 +59,20 @@ class HipchatNotifierTest < ActiveSupport::TestCase
59
59
  assert_nil hipchat.room
60
60
  end
61
61
 
62
+ test "should send hipchat notification with message_template" do
63
+ options = {
64
+ :api_token => 'good_token',
65
+ :room_name => 'room_name',
66
+ :color => 'yellow',
67
+ :message_template => ->(exception) { "This is custom message: '#{exception.message}'" }
68
+ }
69
+
70
+ HipChat::Room.any_instance.expects(:send).with('Exception', "This is custom message: '#{fake_exception.message}'", { :color => 'yellow' })
71
+
72
+ hipchat = ExceptionNotifier::HipchatNotifier.new(options)
73
+ hipchat.call(fake_exception)
74
+ end
75
+
62
76
  private
63
77
 
64
78
  def fake_body
@@ -0,0 +1,85 @@
1
+ require 'test_helper'
2
+ require 'carrier-pigeon'
3
+
4
+ class IrcNotifierTest < ActiveSupport::TestCase
5
+
6
+ test "should send irc notification if properly configured" do
7
+ options = {
8
+ :domain => 'irc.example.com'
9
+ }
10
+
11
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
12
+ /divided by 0/.match(v[:message])
13
+ end
14
+
15
+ irc = ExceptionNotifier::IrcNotifier.new(options)
16
+ irc.call(fake_exception)
17
+ end
18
+
19
+ test "should properly construct URI from constituent parts" do
20
+ options = {
21
+ :nick => 'BadNewsBot',
22
+ :password => 'secret',
23
+ :domain => 'irc.example.com',
24
+ :port => 9999,
25
+ :channel => '#exceptions'
26
+ }
27
+
28
+ CarrierPigeon.expects(:send).with(has_entry(uri: "irc://BadNewsBot:secret@irc.example.com:9999/#exceptions"))
29
+
30
+ irc = ExceptionNotifier::IrcNotifier.new(options)
31
+ irc.call(fake_exception)
32
+ end
33
+
34
+ test "should properly add recipients if specified" do
35
+ options = {
36
+ domain: 'irc.example.com',
37
+ recipients: ['peter', 'michael', 'samir']
38
+ }
39
+
40
+ CarrierPigeon.expects(:send).with(has_key(:uri)) do |v|
41
+ /peter, michael, samir/.match(v[:message])
42
+ end
43
+
44
+ irc = ExceptionNotifier::IrcNotifier.new(options)
45
+ irc.call(fake_exception)
46
+ end
47
+
48
+ test "should properly set miscellaneous options" do
49
+ options = {
50
+ domain: 'irc.example.com',
51
+ ssl: true,
52
+ join: true,
53
+ notice: true,
54
+ prefix: '[test notification]'
55
+ }
56
+
57
+ CarrierPigeon.expects(:send).with(has_entries(
58
+ ssl: true,
59
+ join: true,
60
+ notice: true,
61
+ )) do |v|
62
+ /\[test notification\]/.match(v[:message])
63
+ end
64
+
65
+ irc = ExceptionNotifier::IrcNotifier.new(options)
66
+ irc.call(fake_exception)
67
+ end
68
+
69
+ test "should not send irc notification if badly configured" do
70
+ wrong_params = { domain: '##scriptkiddie.com###'}
71
+ irc = ExceptionNotifier::IrcNotifier.new(wrong_params)
72
+
73
+ assert_nil irc.call(fake_exception)
74
+ end
75
+
76
+ private
77
+
78
+ def fake_exception
79
+ exception = begin
80
+ 5/0
81
+ rescue Exception => e
82
+ e
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,27 @@
1
+ require "test_helper"
2
+
3
+ # To allow sidekiq error handlers to be registered, sidekiq must be in
4
+ # "server mode". This mode is triggered by loading sidekiq/cli. Note this
5
+ # has to be loaded before exception_notification/sidekiq.
6
+ require "sidekiq/cli"
7
+
8
+ require "exception_notification/sidekiq"
9
+
10
+ class MockSidekiqServer
11
+ include ::Sidekiq::ExceptionHandler
12
+ end
13
+
14
+ class SidekiqTest < ActiveSupport::TestCase
15
+ test "should call notify_exception when sidekiq raises an error" do
16
+ server = MockSidekiqServer.new
17
+ message = Hash.new
18
+ exception = RuntimeError.new
19
+
20
+ ExceptionNotifier.expects(:notify_exception).with(
21
+ exception,
22
+ :data => { :sidekiq => message }
23
+ )
24
+
25
+ server.handle_exception(exception, message)
26
+ end
27
+ end
@@ -2,7 +2,7 @@ require 'test_helper'
2
2
 
3
3
  class ExceptionNotifierTest < ActiveSupport::TestCase
4
4
  test "should have default ignored exceptions" do
5
- assert ExceptionNotifier.ignored_exceptions == ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError']
5
+ assert ExceptionNotifier.ignored_exceptions == ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError', 'ActionController::UnknownFormat']
6
6
  end
7
7
 
8
8
  test "should have email notifier registered" do
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: exception_notification
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.1
5
- prerelease:
4
+ version: 4.1.0.rc1
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Jamis Buck
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-09-15 00:00:00.000000000 Z
13
+ date: 2014-04-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: actionmailer
@@ -83,7 +83,7 @@ dependencies:
83
83
  requirements:
84
84
  - - ~>
85
85
  - !ruby/object:Gem::Version
86
- version: '2.0'
86
+ version: '3.0'
87
87
  type: :development
88
88
  prerelease: false
89
89
  version_requirements: !ruby/object:Gem::Requirement
@@ -91,7 +91,7 @@ dependencies:
91
91
  requirements:
92
92
  - - ~>
93
93
  - !ruby/object:Gem::Version
94
- version: '2.0'
94
+ version: '3.0'
95
95
  - !ruby/object:Gem::Dependency
96
96
  name: tinder
97
97
  requirement: !ruby/object:Gem::Requirement
@@ -204,15 +204,28 @@ dependencies:
204
204
  - - ! '>='
205
205
  - !ruby/object:Gem::Version
206
206
  version: 0.11.0
207
+ - !ruby/object:Gem::Dependency
208
+ name: carrier-pigeon
209
+ requirement: !ruby/object:Gem::Requirement
210
+ none: false
211
+ requirements:
212
+ - - ! '>='
213
+ - !ruby/object:Gem::Version
214
+ version: 0.7.0
215
+ type: :development
216
+ prerelease: false
217
+ version_requirements: !ruby/object:Gem::Requirement
218
+ none: false
219
+ requirements:
220
+ - - ! '>='
221
+ - !ruby/object:Gem::Version
222
+ version: 0.7.0
207
223
  description:
208
224
  email: smartinez87@gmail.com
209
225
  executables: []
210
226
  extensions: []
211
227
  extra_rdoc_files: []
212
228
  files:
213
- - .gemtest
214
- - .gitignore
215
- - .travis.yml
216
229
  - Appraisals
217
230
  - CHANGELOG.rdoc
218
231
  - CONTRIBUTING.md
@@ -240,6 +253,7 @@ files:
240
253
  - lib/exception_notifier/campfire_notifier.rb
241
254
  - lib/exception_notifier/email_notifier.rb
242
255
  - lib/exception_notifier/hipchat_notifier.rb
256
+ - lib/exception_notifier/irc_notifier.rb
243
257
  - lib/exception_notifier/notifier.rb
244
258
  - lib/exception_notifier/views/exception_notifier/_backtrace.html.erb
245
259
  - lib/exception_notifier/views/exception_notifier/_backtrace.text.erb
@@ -318,6 +332,8 @@ files:
318
332
  - test/exception_notifier/campfire_notifier_test.rb
319
333
  - test/exception_notifier/email_notifier_test.rb
320
334
  - test/exception_notifier/hipchat_notifier_test.rb
335
+ - test/exception_notifier/irc_notifier_test.rb
336
+ - test/exception_notifier/sidekiq_test.rb
321
337
  - test/exception_notifier/webhook_notifier_test.rb
322
338
  - test/exception_notifier_test.rb
323
339
  - test/test_helper.rb
@@ -405,6 +421,8 @@ test_files:
405
421
  - test/exception_notifier/campfire_notifier_test.rb
406
422
  - test/exception_notifier/email_notifier_test.rb
407
423
  - test/exception_notifier/hipchat_notifier_test.rb
424
+ - test/exception_notifier/irc_notifier_test.rb
425
+ - test/exception_notifier/sidekiq_test.rb
408
426
  - test/exception_notifier/webhook_notifier_test.rb
409
427
  - test/exception_notifier_test.rb
410
428
  - test/test_helper.rb
data/.gemtest DELETED
File without changes
data/.gitignore DELETED
@@ -1,2 +0,0 @@
1
- /coverage/
2
- *.gemfile.lock
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 1.9.3
4
- - 2.0.0
5
- gemfile:
6
- - Gemfile
7
- - gemfiles/rails3_1.gemfile
8
- - gemfiles/rails3_2.gemfile
9
- - gemfiles/rails4_0.gemfile