exception_notification 4.3.0 → 4.5.0

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.
Files changed (131) hide show
  1. checksums.yaml +5 -5
  2. data/Appraisals +4 -2
  3. data/CHANGELOG.rdoc +47 -0
  4. data/CONTRIBUTING.md +18 -0
  5. data/Gemfile +3 -1
  6. data/README.md +97 -945
  7. data/Rakefile +4 -2
  8. data/docs/notifiers/campfire.md +50 -0
  9. data/docs/notifiers/custom.md +42 -0
  10. data/docs/notifiers/datadog.md +51 -0
  11. data/docs/notifiers/email.md +195 -0
  12. data/docs/notifiers/google_chat.md +31 -0
  13. data/docs/notifiers/hipchat.md +66 -0
  14. data/docs/notifiers/irc.md +97 -0
  15. data/docs/notifiers/mattermost.md +115 -0
  16. data/docs/notifiers/slack.md +161 -0
  17. data/docs/notifiers/sns.md +37 -0
  18. data/docs/notifiers/teams.md +54 -0
  19. data/docs/notifiers/webhook.md +60 -0
  20. data/examples/sample_app.rb +56 -0
  21. data/examples/sinatra/Gemfile +8 -6
  22. data/examples/sinatra/config.ru +3 -1
  23. data/examples/sinatra/sinatra_app.rb +19 -11
  24. data/exception_notification.gemspec +30 -24
  25. data/gemfiles/{rails4_0.gemfile → rails5_2.gemfile} +2 -2
  26. data/gemfiles/{rails4_1.gemfile → rails6_0.gemfile} +2 -2
  27. data/gemfiles/{rails4_2.gemfile → rails6_1.gemfile} +2 -2
  28. data/gemfiles/{rails5_0.gemfile → rails7_0.gemfile} +2 -2
  29. data/lib/exception_notification/rack.rb +28 -30
  30. data/lib/exception_notification/rails.rb +2 -0
  31. data/lib/exception_notification/resque.rb +10 -10
  32. data/lib/exception_notification/sidekiq.rb +10 -12
  33. data/lib/exception_notification/version.rb +5 -0
  34. data/lib/exception_notification.rb +3 -0
  35. data/lib/exception_notifier/base_notifier.rb +10 -5
  36. data/lib/exception_notifier/datadog_notifier.rb +156 -0
  37. data/lib/exception_notifier/email_notifier.rb +73 -88
  38. data/lib/exception_notifier/google_chat_notifier.rb +27 -119
  39. data/lib/exception_notifier/hipchat_notifier.rb +13 -12
  40. data/lib/exception_notifier/irc_notifier.rb +36 -33
  41. data/lib/exception_notifier/mattermost_notifier.rb +54 -137
  42. data/lib/exception_notifier/modules/backtrace_cleaner.rb +2 -2
  43. data/lib/exception_notifier/modules/error_grouping.rb +24 -13
  44. data/lib/exception_notifier/modules/formatter.rb +125 -0
  45. data/lib/exception_notifier/notifier.rb +9 -6
  46. data/lib/exception_notifier/slack_notifier.rb +65 -40
  47. data/lib/exception_notifier/sns_notifier.rb +23 -13
  48. data/lib/exception_notifier/teams_notifier.rb +67 -46
  49. data/lib/exception_notifier/views/exception_notifier/_backtrace.html.erb +1 -1
  50. data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +1 -1
  51. data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -1
  52. data/lib/exception_notifier/views/exception_notifier/exception_notification.html.erb +2 -2
  53. data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +2 -2
  54. data/lib/exception_notifier/webhook_notifier.rb +17 -14
  55. data/lib/exception_notifier.rb +65 -10
  56. data/lib/generators/exception_notification/install_generator.rb +11 -5
  57. data/lib/generators/exception_notification/templates/{exception_notification.rb → exception_notification.rb.erb} +13 -11
  58. data/test/exception_notification/rack_test.rb +75 -13
  59. data/test/exception_notification/resque_test.rb +54 -0
  60. data/test/exception_notifier/datadog_notifier_test.rb +153 -0
  61. data/test/exception_notifier/email_notifier_test.rb +275 -153
  62. data/test/exception_notifier/google_chat_notifier_test.rb +158 -101
  63. data/test/exception_notifier/hipchat_notifier_test.rb +84 -81
  64. data/test/exception_notifier/irc_notifier_test.rb +36 -34
  65. data/test/exception_notifier/mattermost_notifier_test.rb +213 -67
  66. data/test/exception_notifier/modules/error_grouping_test.rb +41 -40
  67. data/test/exception_notifier/modules/formatter_test.rb +152 -0
  68. data/test/exception_notifier/sidekiq_test.rb +9 -17
  69. data/test/exception_notifier/slack_notifier_test.rb +66 -63
  70. data/test/exception_notifier/sns_notifier_test.rb +84 -32
  71. data/test/exception_notifier/teams_notifier_test.rb +25 -26
  72. data/test/exception_notifier/webhook_notifier_test.rb +52 -48
  73. data/test/exception_notifier_test.rb +150 -41
  74. data/test/support/exception_notifier_helper.rb +14 -0
  75. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.html.erb +0 -0
  76. data/test/{dummy/app → support}/views/exception_notifier/_new_bkg_section.text.erb +0 -0
  77. data/test/{dummy/app → support}/views/exception_notifier/_new_section.html.erb +0 -0
  78. data/test/{dummy/app → support}/views/exception_notifier/_new_section.text.erb +0 -0
  79. data/test/test_helper.rb +14 -13
  80. metadata +134 -175
  81. data/gemfiles/rails5_1.gemfile +0 -7
  82. data/lib/exception_notifier/campfire_notifier.rb +0 -40
  83. data/test/dummy/.gitignore +0 -4
  84. data/test/dummy/Rakefile +0 -7
  85. data/test/dummy/app/controllers/application_controller.rb +0 -3
  86. data/test/dummy/app/controllers/posts_controller.rb +0 -30
  87. data/test/dummy/app/helpers/application_helper.rb +0 -2
  88. data/test/dummy/app/helpers/posts_helper.rb +0 -2
  89. data/test/dummy/app/models/post.rb +0 -2
  90. data/test/dummy/app/views/layouts/application.html.erb +0 -14
  91. data/test/dummy/app/views/posts/_form.html.erb +0 -0
  92. data/test/dummy/app/views/posts/new.html.erb +0 -0
  93. data/test/dummy/app/views/posts/show.html.erb +0 -0
  94. data/test/dummy/config/application.rb +0 -42
  95. data/test/dummy/config/boot.rb +0 -6
  96. data/test/dummy/config/database.yml +0 -22
  97. data/test/dummy/config/environment.rb +0 -17
  98. data/test/dummy/config/environments/development.rb +0 -25
  99. data/test/dummy/config/environments/production.rb +0 -50
  100. data/test/dummy/config/environments/test.rb +0 -35
  101. data/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  102. data/test/dummy/config/initializers/inflections.rb +0 -10
  103. data/test/dummy/config/initializers/mime_types.rb +0 -5
  104. data/test/dummy/config/initializers/secret_token.rb +0 -8
  105. data/test/dummy/config/initializers/session_store.rb +0 -8
  106. data/test/dummy/config/locales/en.yml +0 -5
  107. data/test/dummy/config/routes.rb +0 -3
  108. data/test/dummy/config.ru +0 -4
  109. data/test/dummy/db/migrate/20110729022608_create_posts.rb +0 -15
  110. data/test/dummy/db/schema.rb +0 -24
  111. data/test/dummy/db/seeds.rb +0 -7
  112. data/test/dummy/lib/tasks/.gitkeep +0 -0
  113. data/test/dummy/public/404.html +0 -26
  114. data/test/dummy/public/422.html +0 -26
  115. data/test/dummy/public/500.html +0 -26
  116. data/test/dummy/public/favicon.ico +0 -0
  117. data/test/dummy/public/images/rails.png +0 -0
  118. data/test/dummy/public/index.html +0 -239
  119. data/test/dummy/public/javascripts/application.js +0 -2
  120. data/test/dummy/public/javascripts/controls.js +0 -965
  121. data/test/dummy/public/javascripts/dragdrop.js +0 -974
  122. data/test/dummy/public/javascripts/effects.js +0 -1123
  123. data/test/dummy/public/javascripts/prototype.js +0 -6001
  124. data/test/dummy/public/javascripts/rails.js +0 -191
  125. data/test/dummy/public/robots.txt +0 -5
  126. data/test/dummy/public/stylesheets/.gitkeep +0 -0
  127. data/test/dummy/public/stylesheets/scaffold.css +0 -56
  128. data/test/dummy/script/rails +0 -6
  129. data/test/dummy/test/functional/posts_controller_test.rb +0 -237
  130. data/test/dummy/test/test_helper.rb +0 -7
  131. data/test/exception_notifier/campfire_notifier_test.rb +0 -120
@@ -0,0 +1,161 @@
1
+ ### Slack notifier
2
+
3
+ This notifier sends notifications to a slack channel using the slack-notifier gem.
4
+
5
+ #### Usage
6
+
7
+ Just add the [slack-notifier](https://github.com/stevenosloan/slack-notifier) gem to your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'slack-notifier'
11
+ ```
12
+
13
+ To configure it, you need to set at least the 'webhook_url' option, like this:
14
+
15
+ ```ruby
16
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
17
+ email: {
18
+ email_prefix: '[PREFIX] ',
19
+ sender_address: %{"notifier" <notifier@example.com>},
20
+ exception_recipients: %w{exceptions@example.com}
21
+ },
22
+ slack: {
23
+ webhook_url: '[Your webhook url]',
24
+ channel: '#exceptions',
25
+ additional_parameters: {
26
+ icon_url: 'http://image.jpg',
27
+ mrkdwn: true
28
+ }
29
+ }
30
+ ```
31
+
32
+ The slack notification will include any data saved under `env['exception_notifier.exception_data']`.
33
+
34
+ An example of how to send the server name to Slack in Rails (put this code in application_controller.rb):
35
+
36
+ ```ruby
37
+ before_action :set_notification
38
+
39
+ def set_notification
40
+ request.env['exception_notifier.exception_data'] = { 'server' => request.env['SERVER_NAME'] }
41
+ # can be any key-value pairs
42
+ end
43
+ ```
44
+
45
+ If you find this too verbose, you can determine to exclude certain information by doing the following:
46
+
47
+ ```ruby
48
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
49
+ slack: {
50
+ webhook_url: '[Your webhook url]',
51
+ channel: '#exceptions',
52
+ additional_parameters: {
53
+ icon_url: 'http://image.jpg',
54
+ mrkdwn: true
55
+ },
56
+ ignore_data_if: lambda {|key, value|
57
+ "#{key}" == 'key_to_ignore' || value.is_a?(ClassToBeIgnored)
58
+ }
59
+ }
60
+ ```
61
+
62
+ Any evaluation to `true` will cause the key / value pair not be be sent along to Slack.
63
+
64
+
65
+ the `slack-notifier` gem allows to override the channel default value, if you ever
66
+ need to send a notification to a different slack channel. Simply add the
67
+ `channel` option when calling `.notify_exception`
68
+
69
+ ```ruby
70
+ ExceptionNotifier.notify_exception(
71
+ exception,
72
+ env: request.env,
73
+ channel: '#my-custom-channel', # Make sure the channel name starts with `#`
74
+ data: {
75
+ error: error_variable,
76
+ server: server_name
77
+ }
78
+ )
79
+ ```
80
+
81
+ If you ever need to add more `slack-notifier` specific options, and
82
+ particularly to the `#ping` method of the slack notifier, you can use
83
+ the `pre_callback` option when defining the middleware.
84
+ ```ruby
85
+ pre_callback: proc { |opts, _notifier, _backtrace, _message, message_opts|
86
+ message_opts[:channel] = opts[:channel] if opts.key?(:channel)
87
+ }
88
+
89
+ ```
90
+ - `message_opts` is the hash you want to append to if you need to add an option.
91
+ - `options` is the hash containing the values when you call
92
+ `ExceptionNotification.notify_exception`
93
+
94
+ An example implementation would be:
95
+ ```ruby
96
+ config.middleware.use ExceptionNotification::Rack,
97
+ slack: {
98
+ webhook_url: '[Your webhook url]',
99
+ pre_callback: proc { |opts, _notifier, _backtrace, _message, message_opts|
100
+ message_opts[:ping_option] = opts[:ping_option] if
101
+ opts.key?(:ping_option)
102
+ }
103
+ },
104
+ error_grouping: true
105
+ ```
106
+ Then when calling from within your application code:
107
+ ```ruby
108
+ ExceptionNotifier.notify_exception(
109
+ exception,
110
+ env: request.env,
111
+ ping_option: 'value',
112
+ # this will be passed to the slack notifier's `#ping`
113
+ # method, as a parameter. The `:pre_callback` hook will catch it
114
+ # and do that for you.
115
+ # Helpful, if the API evolves, you only need to update
116
+ # the `slack-notifier` gem
117
+ data: {
118
+ error: error_variable,
119
+ server: server_name
120
+ }
121
+ )
122
+
123
+ ```
124
+ #### Options
125
+
126
+ ##### webhook_url
127
+
128
+ *String, required*
129
+
130
+ The Incoming WebHook URL on slack.
131
+
132
+ ##### channel
133
+
134
+ *String, optional*
135
+
136
+ Message will appear in this channel. Defaults to the channel you set as such on slack.
137
+
138
+ ##### username
139
+
140
+ *String, optional*
141
+
142
+ Username of the bot. Defaults to the name you set as such on slack
143
+
144
+ ##### custom_hook
145
+
146
+ *String, optional*
147
+
148
+ Custom hook name. See [slack-notifier](https://github.com/stevenosloan/slack-notifier#custom-hook-name) for
149
+ more information. Default: 'incoming-webhook'
150
+
151
+ ##### additional_parameters
152
+
153
+ *Hash of strings, optional*
154
+
155
+ Contains additional payload for a message (e.g avatar, attachments, etc). See [slack-notifier](https://github.com/stevenosloan/slack-notifier#additional-parameters) for more information.. Default: '{}'
156
+
157
+ ##### additional_fields
158
+
159
+ *Array of Hashes, optional*
160
+
161
+ Contains additional fields that will be added to the attachement. See [Slack documentation](https://api.slack.com/docs/message-attachments).
@@ -0,0 +1,37 @@
1
+ ### Amazon SNS Notifier
2
+
3
+ Notify all exceptions Amazon - Simple Notification Service: [SNS](https://aws.amazon.com/sns/).
4
+
5
+ #### Usage
6
+
7
+ Add the [aws-sdk-sns](https://github.com/aws/aws-sdk-ruby/tree/master/gems/aws-sdk-sns) gem to your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'aws-sdk-sns', '~> 1.5'
11
+ ```
12
+
13
+ To configure it, you **need** to set 3 required options for aws: `region`, `access_key_id` and `secret_access_key`, and one more option for sns: `topic_arn`.
14
+
15
+ ```ruby
16
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
17
+ sns: {
18
+ region: 'us-east-x',
19
+ access_key_id: 'access_key_id',
20
+ secret_access_key: 'secret_access_key',
21
+ topic_arn: 'arn:aws:sns:us-east-x:XXXX:my-topic'
22
+ }
23
+ ```
24
+
25
+ ##### sns_prefix
26
+ *String, optional *
27
+
28
+ Prefix in the notification subject, by default: "[Error]"
29
+
30
+ ##### backtrace_lines
31
+ *Integer, optional *
32
+
33
+ Number of backtrace lines to be displayed in the notification message. By default: 10
34
+
35
+ #### Note:
36
+ * You may need to update your previous `aws-sdk-*` gems in order to setup `aws-sdk-sns` correctly.
37
+ * If you need any further information about the available regions or any other SNS related topic consider: [SNS faqs](https://aws.amazon.com/sns/faqs/)
@@ -0,0 +1,54 @@
1
+ ### Teams notifier
2
+
3
+ Post notification in a Microsoft Teams channel via [Incoming Webhook Connector](https://docs.microsoft.com/en-us/outlook/actionable-messages/actionable-messages-via-connectors)
4
+ Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
5
+
6
+ ```ruby
7
+ gem 'httparty'
8
+ ```
9
+
10
+ To configure it, you **need** to set the `webhook_url` option.
11
+ If you are using GitLab for issue tracking, you can specify `git_url` as follows to add a *Create issue* button in your notification.
12
+ By default this will use your Rails application name to match the git repository. If yours differs, you can specify `app_name`.
13
+ By that same notion, you may also set a `jira_url` to get a button that will send you to the New Issue screen in Jira.
14
+
15
+ ```ruby
16
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
17
+ email: {
18
+ email_prefix: "[PREFIX] ",
19
+ sender_address: %{"notifier" <notifier@example.com>},
20
+ exception_recipients: %w{exceptions@example.com}
21
+ },
22
+ teams: {
23
+ webhook_url: 'https://outlook.office.com/webhook/your-guid/IncomingWebhook/team-guid',
24
+ git_url: 'https://your-gitlab.com/Group/Project',
25
+ jira_url: 'https://your-jira.com'
26
+ }
27
+ ```
28
+
29
+ #### Options
30
+
31
+ ##### webhook_url
32
+
33
+ *String, required*
34
+
35
+ The Incoming WebHook URL on Teams.
36
+
37
+ ##### git_url
38
+
39
+ *String, optional*
40
+
41
+ Url of your gitlab or github with your organisation name for issue creation link (Eg: `github.com/aschen`). Defaults to nil and doesn't add link to the notification.
42
+
43
+ ##### jira_url
44
+
45
+ *String, optional*
46
+
47
+ Url of your Jira instance, adds button for Create Issue screen. Defaults to nil and doesn't add a button to the card.
48
+
49
+ ##### app_name
50
+
51
+ *String, optional*
52
+
53
+ Your application name used for git issue creation link. Defaults to `Rails.application.class.module_parent_name.underscore` for Rails versions >= 6;
54
+ `Rails.application.class.parent_name.underscore` otherwise.
@@ -0,0 +1,60 @@
1
+ ### WebHook notifier
2
+
3
+ This notifier ships notifications over the HTTP protocol.
4
+
5
+ #### Usage
6
+
7
+ Just add the [HTTParty](https://github.com/jnunemaker/httparty) gem to your `Gemfile`:
8
+
9
+ ```ruby
10
+ gem 'httparty'
11
+ ```
12
+
13
+ To configure it, you need to set the `url` option, like this:
14
+
15
+ ```ruby
16
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
17
+ email: {
18
+ email_prefix: '[PREFIX] ',
19
+ sender_address: %{"notifier" <notifier@example.com>},
20
+ exception_recipients: %w{exceptions@example.com}
21
+ },
22
+ webhook: {
23
+ url: 'http://domain.com:5555/hubot/path'
24
+ }
25
+ ```
26
+
27
+ By default, the WebhookNotifier will call the URLs using the POST method. But, you can change this using the `http_method` option.
28
+
29
+ ```ruby
30
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
31
+ email: {
32
+ email_prefix: '[PREFIX] ',
33
+ sender_address: %{"notifier" <notifier@example.com>},
34
+ exception_recipients: %w{exceptions@example.com}
35
+ },
36
+ webhook: {
37
+ url: 'http://domain.com:5555/hubot/path',
38
+ http_method: :get
39
+ }
40
+ ```
41
+
42
+ Besides the `url` and `http_method` options, all the other options are passed directly to HTTParty. Thus, if the HTTP server requires authentication, you can include the following options:
43
+
44
+ ```ruby
45
+ Rails.application.config.middleware.use ExceptionNotification::Rack,
46
+ email: {
47
+ email_prefix: '[PREFIX] ',
48
+ sender_address: %{"notifier" <notifier@example.com>},
49
+ exception_recipients: %w{exceptions@example.com}
50
+ },
51
+ webhook: {
52
+ url: 'http://domain.com:5555/hubot/path',
53
+ basic_auth: {
54
+ username: 'alice',
55
+ password: 'password'
56
+ }
57
+ }
58
+ ```
59
+
60
+ For more HTTParty options, check out the [documentation](https://github.com/jnunemaker/httparty).
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ # -------------------------------------------
4
+ # To run the application: ruby examples/sample_app.rb
5
+ # -------------------------------------------
6
+
7
+ require 'bundler/inline'
8
+
9
+ gemfile do
10
+ source 'https://rubygems.org'
11
+
12
+ gem 'rails', '5.0.0'
13
+ gem 'exception_notification', '4.3.0'
14
+ gem 'httparty', '0.15.7'
15
+ end
16
+
17
+ class SampleApp < Rails::Application
18
+ config.middleware.use ExceptionNotification::Rack,
19
+ webhook: {
20
+ url: 'http://example.com'
21
+ }
22
+
23
+ config.secret_key_base = 'my secret key base'
24
+
25
+ Rails.logger = Logger.new($stdout)
26
+
27
+ routes.draw do
28
+ get '/', to: 'exceptions#index'
29
+ end
30
+ end
31
+
32
+ require 'action_controller/railtie'
33
+
34
+ class ExceptionsController < ActionController::Base
35
+ def index
36
+ raise 'Sample exception raised, you should receive a notification!'
37
+ end
38
+ end
39
+
40
+ require 'minitest/autorun'
41
+
42
+ class Test < Minitest::Test
43
+ include Rack::Test::Methods
44
+
45
+ def test_raise_exception
46
+ get '/'
47
+
48
+ assert last_response.server_error?
49
+ end
50
+
51
+ private
52
+
53
+ def app
54
+ Rails.application
55
+ end
56
+ end
@@ -1,8 +1,10 @@
1
- source "https://rubygems.org"
1
+ # frozen_string_literal: true
2
2
 
3
- gem "exception_notification", path: "../../"
3
+ source 'https://rubygems.org'
4
4
 
5
- gem "thin", "~> 1.5.1"
6
- gem "sinatra", "~> 1.3.5"
7
- gem "foreman"
8
- gem "mailcatcher"
5
+ gem 'exception_notification', path: '../../'
6
+
7
+ gem 'foreman'
8
+ gem 'mailcatcher'
9
+ gem 'sinatra', '~> 1.3.5'
10
+ gem 'thin', '~> 1.5.1'
@@ -1,3 +1,5 @@
1
- require ::File.expand_path('../sinatra_app', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ require ::File.expand_path('../sinatra_app', __FILE__)
2
4
 
3
5
  run SinatraApp
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rubygems'
2
4
  require 'bundler/setup'
3
5
  require 'sinatra/base'
@@ -5,27 +7,33 @@ require 'exception_notification'
5
7
 
6
8
  class SinatraApp < Sinatra::Base
7
9
  use Rack::Config do |env|
8
- env["action_dispatch.parameter_filter"] = [:password] # This is highly recommended. It will prevent the ExceptionNotification email from including your users' passwords
10
+ # This is highly recommended. It will prevent the ExceptionNotification email from including your users' passwords
11
+ env['action_dispatch.parameter_filter'] = [:password]
9
12
  end
10
13
 
11
14
  use ExceptionNotification::Rack,
12
- :email => {
13
- :email_prefix => "[Example] ",
14
- :sender_address => %{"notifier" <notifier@example.com>},
15
- :exception_recipients => %w{exceptions@example.com},
16
- :smtp_settings => { :address => "localhost", :port => 1025 }
17
- }
15
+ email: {
16
+ email_prefix: '[Example] ',
17
+ sender_address: %("notifier" <notifier@example.com>),
18
+ exception_recipients: %w[exceptions@example.com],
19
+ smtp_settings: {
20
+ address: 'localhost',
21
+ port: 1025
22
+ }
23
+ }
18
24
 
19
25
  get '/' do
20
26
  raise StandardError, "ERROR: #{params[:error]}" unless params[:error].blank?
21
- '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> !'
27
+
28
+ 'Everything is fine! Now, lets break things clicking <a href="/?error=ops"> here </a>.' \
29
+ 'Dont forget to see the emails at <a href="http://localhost:1080">mailcatcher</a> !'
22
30
  end
23
31
 
24
32
  get '/background_notification' do
25
33
  begin
26
- 1/0
27
- rescue Exception => e
28
- ExceptionNotifier.notify_exception(e, :data => {:msg => "Cannot divide by zero!"})
34
+ 1 / 0
35
+ rescue StandardError => e
36
+ ExceptionNotifier.notify_exception(e, data: { msg: 'Cannot divide by zero!' })
29
37
  end
30
38
  'Check email at <a href="http://localhost:1080">mailcatcher</a>.'
31
39
  end
@@ -1,14 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require File.expand_path('lib/exception_notification/version', __dir__)
4
+
1
5
  Gem::Specification.new do |s|
2
6
  s.name = 'exception_notification'
3
- s.version = '4.3.0'
4
- s.authors = ["Jamis Buck", "Josh Peek"]
5
- s.date = %q{2018-11-22}
6
- s.summary = "Exception notification for Rails apps"
7
- s.homepage = "https://smartinez87.github.io/exception_notification/"
8
- s.email = "smartinez87@gmail.com"
9
- s.license = "MIT"
7
+ s.version = ExceptionNotification::VERSION
8
+ s.authors = ['Jamis Buck', 'Josh Peek']
9
+ s.date = '2022-01-20'
10
+ s.summary = 'Exception notification for Rails apps'
11
+ s.homepage = 'https://smartinez87.github.io/exception_notification/'
12
+ s.email = 'smartinez87@gmail.com'
13
+ s.license = 'MIT'
10
14
 
11
- s.required_ruby_version = '>= 2.0'
15
+ s.required_ruby_version = '>= 2.3'
12
16
  s.required_rubygems_version = '>= 1.8.11'
13
17
 
14
18
  s.files = `git ls-files`.split("\n")
@@ -16,21 +20,23 @@ Gem::Specification.new do |s|
16
20
  s.test_files = `git ls-files -- test`.split("\n")
17
21
  s.require_path = 'lib'
18
22
 
19
- s.add_dependency("actionmailer", ">= 4.0", "< 6")
20
- s.add_dependency("activesupport", ">= 4.0", "< 6")
23
+ s.add_dependency('actionmailer', '>= 5.2', '< 8')
24
+ s.add_dependency('activesupport', '>= 5.2', '< 8')
21
25
 
22
- s.add_development_dependency "rails", ">= 4.0", "< 6"
23
- s.add_development_dependency "resque", "~> 1.2.0"
24
- # Sidekiq 3.2.2 does not support Ruby 1.9.
25
- s.add_development_dependency "sidekiq", "~> 3.0.0", "< 3.2.2"
26
- s.add_development_dependency "tinder", "~> 1.8"
27
- s.add_development_dependency "httparty", "~> 0.10.2"
28
- s.add_development_dependency "mocha", ">= 0.13.0"
29
- s.add_development_dependency "sqlite3", ">= 1.3.4"
30
- s.add_development_dependency "coveralls", "~> 0.8.2"
31
- s.add_development_dependency "appraisal", "~> 2.0.0"
32
- s.add_development_dependency "hipchat", ">= 1.0.0"
33
- s.add_development_dependency "carrier-pigeon", ">= 0.7.0"
34
- s.add_development_dependency "slack-notifier", ">= 1.0.0"
35
- s.add_development_dependency "aws-sdk-sns", "~> 1"
26
+ s.add_development_dependency 'appraisal', '~> 2.2.0'
27
+ s.add_development_dependency 'aws-sdk-sns', '~> 1'
28
+ s.add_development_dependency 'carrier-pigeon', '>= 0.7.0'
29
+ s.add_development_dependency 'coveralls', '~> 0.8.2'
30
+ s.add_development_dependency 'dogapi', '>= 1.23.0'
31
+ s.add_development_dependency 'hipchat', '>= 1.0.0'
32
+ s.add_development_dependency 'httparty', '~> 0.10.2'
33
+ s.add_development_dependency 'mocha', '>= 0.13.0'
34
+ s.add_development_dependency 'mock_redis', '~> 0.19.0'
35
+ s.add_development_dependency 'net-smtp'
36
+ s.add_development_dependency 'rails', '>= 5.2', '< 8'
37
+ s.add_development_dependency 'resque', '~> 1.8.0'
38
+ s.add_development_dependency 'rubocop', '0.78.0'
39
+ s.add_development_dependency 'sidekiq', '>= 5.0.4'
40
+ s.add_development_dependency 'slack-notifier', '>= 1.0.0'
41
+ s.add_development_dependency 'timecop', '~> 0.9.0'
36
42
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.0.5"
5
+ gem "rails", "~> 5.2.0"
6
6
 
7
- gemspec :path => "../"
7
+ gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.1.1"
5
+ gem "rails", "~> 6.0.0"
6
6
 
7
- gemspec :path => "../"
7
+ gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 4.2.0"
5
+ gem "rails", "~> 6.1.0"
6
6
 
7
- gemspec :path => "../"
7
+ gemspec path: "../"
@@ -2,6 +2,6 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 5.0.0"
5
+ gem "rails", "~> 7.0.0"
6
6
 
7
- gemspec :path => "../"
7
+ gemspec path: "../"
@@ -1,19 +1,23 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ExceptionNotification
2
4
  class Rack
3
- class CascadePassException < Exception; end
5
+ class CascadePassException < RuntimeError; end
4
6
 
5
7
  def initialize(app, options = {})
6
8
  @app = app
7
9
 
8
- ExceptionNotifier.ignored_exceptions = options.delete(:ignore_exceptions) if options.key?(:ignore_exceptions)
9
- ExceptionNotifier.error_grouping = options.delete(:error_grouping) if options.key?(:error_grouping)
10
- ExceptionNotifier.error_grouping_period = options.delete(:error_grouping_period) if options.key?(:error_grouping_period)
11
- ExceptionNotifier.notification_trigger = options.delete(:notification_trigger) if options.key?(:notification_trigger)
10
+ ExceptionNotifier.tap do |en|
11
+ en.ignored_exceptions = options.delete(:ignore_exceptions) if options.key?(:ignore_exceptions)
12
+ en.error_grouping = options.delete(:error_grouping) if options.key?(:error_grouping)
13
+ en.error_grouping_period = options.delete(:error_grouping_period) if options.key?(:error_grouping_period)
14
+ en.notification_trigger = options.delete(:notification_trigger) if options.key?(:notification_trigger)
12
15
 
13
- if options.key?(:error_grouping_cache)
14
- ExceptionNotifier.error_grouping_cache = options.delete(:error_grouping_cache)
15
- elsif defined?(Rails)
16
- ExceptionNotifier.error_grouping_cache = Rails.cache
16
+ if options.key?(:error_grouping_cache)
17
+ en.error_grouping_cache = options.delete(:error_grouping_cache)
18
+ elsif defined?(Rails) && Rails.respond_to?(:cache)
19
+ en.error_grouping_cache = Rails.cache
20
+ end
17
21
  end
18
22
 
19
23
  if options.key?(:ignore_if)
@@ -23,13 +27,17 @@ module ExceptionNotification
23
27
  end
24
28
  end
25
29
 
26
- if options.key?(:ignore_crawlers)
27
- ignore_crawlers = options.delete(:ignore_crawlers)
28
- ExceptionNotifier.ignore_if do |exception, opts|
29
- opts.key?(:env) && from_crawler(opts[:env], ignore_crawlers)
30
+ if options.key?(:ignore_notifier_if)
31
+ rack_ignore_by_notifier = options.delete(:ignore_notifier_if)
32
+ rack_ignore_by_notifier.each do |notifier, proc|
33
+ ExceptionNotifier.ignore_notifier_if(notifier) do |exception, opts|
34
+ opts.key?(:env) && proc.call(opts[:env], exception)
35
+ end
30
36
  end
31
37
  end
32
38
 
39
+ ExceptionNotifier.ignore_crawlers(options.delete(:ignore_crawlers)) if options.key?(:ignore_crawlers)
40
+
33
41
  @ignore_cascade_pass = options.delete(:ignore_cascade_pass) { true }
34
42
 
35
43
  options.each do |notifier_name, opts|
@@ -38,31 +46,21 @@ module ExceptionNotification
38
46
  end
39
47
 
40
48
  def call(env)
41
- _, headers, _ = response = @app.call(env)
49
+ _, headers, = response = @app.call(env)
42
50
 
43
51
  if !@ignore_cascade_pass && headers['X-Cascade'] == 'pass'
44
- msg = "This exception means that the preceding Rack middleware set the 'X-Cascade' header to 'pass' -- in " <<
45
- "Rails, this often means that the route was not found (404 error)."
52
+ msg = "This exception means that the preceding Rack middleware set the 'X-Cascade' header to 'pass' -- in " \
53
+ 'Rails, this often means that the route was not found (404 error).'
46
54
  raise CascadePassException, msg
47
55
  end
48
56
 
49
57
  response
50
- rescue Exception => exception
51
- if ExceptionNotifier.notify_exception(exception, :env => env)
52
- env['exception_notifier.delivered'] = true
53
- end
54
-
55
- raise exception unless exception.is_a?(CascadePassException)
56
- response
57
- end
58
+ rescue Exception => e
59
+ env['exception_notifier.delivered'] = true if ExceptionNotifier.notify_exception(e, env: env)
58
60
 
59
- private
61
+ raise e unless e.is_a?(CascadePassException)
60
62
 
61
- def from_crawler(env, ignored_crawlers)
62
- agent = env['HTTP_USER_AGENT']
63
- Array(ignored_crawlers).any? do |crawler|
64
- agent =~ Regexp.new(crawler)
65
- end
63
+ response
66
64
  end
67
65
  end
68
66
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ExceptionNotification
2
4
  class Engine < ::Rails::Engine
3
5
  config.exception_notification = ExceptionNotifier