exception_notification 2.5.2 → 2.6.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/Gemfile.lock +67 -56
- data/README.md +188 -46
- data/exception_notification.gemspec +3 -2
- data/lib/exception_notifier.rb +34 -4
- data/lib/exception_notifier/notifier.rb +49 -15
- data/lib/exception_notifier/views/exception_notifier/_data.text.erb +1 -0
- data/lib/exception_notifier/views/exception_notifier/_environment.text.erb +3 -3
- data/lib/exception_notifier/views/exception_notifier/_request.text.erb +1 -0
- data/lib/exception_notifier/views/exception_notifier/_session.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/background_exception_notification.text.erb +1 -1
- data/lib/exception_notifier/views/exception_notifier/exception_notification.text.erb +16 -5
- data/test/background_exception_notification_test.rb +14 -5
- data/test/dummy/Gemfile.lock +1 -1
- data/test/dummy/app/views/exception_notifier/_new_section.text.erb +1 -0
- data/test/dummy/config/environment.rb +2 -1
- data/test/dummy/test/functional/posts_controller_test.rb +98 -3
- data/test/exception_notification_test.rb +25 -2
- metadata +61 -78
data/Gemfile.lock
CHANGED
@@ -1,78 +1,89 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
exception_notification (2.
|
4
|
+
exception_notification (2.5.2)
|
5
5
|
actionmailer (>= 3.0.4)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: http://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
rack (~> 1.2
|
21
|
-
rack-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
arel (
|
38
|
-
builder (
|
39
|
-
erubis (2.
|
40
|
-
|
41
|
-
i18n (0.
|
42
|
-
|
43
|
-
|
10
|
+
actionmailer (3.2.3)
|
11
|
+
actionpack (= 3.2.3)
|
12
|
+
mail (~> 2.4.4)
|
13
|
+
actionpack (3.2.3)
|
14
|
+
activemodel (= 3.2.3)
|
15
|
+
activesupport (= 3.2.3)
|
16
|
+
builder (~> 3.0.0)
|
17
|
+
erubis (~> 2.7.0)
|
18
|
+
journey (~> 1.0.1)
|
19
|
+
rack (~> 1.4.0)
|
20
|
+
rack-cache (~> 1.2)
|
21
|
+
rack-test (~> 0.6.1)
|
22
|
+
sprockets (~> 2.1.2)
|
23
|
+
activemodel (3.2.3)
|
24
|
+
activesupport (= 3.2.3)
|
25
|
+
builder (~> 3.0.0)
|
26
|
+
activerecord (3.2.3)
|
27
|
+
activemodel (= 3.2.3)
|
28
|
+
activesupport (= 3.2.3)
|
29
|
+
arel (~> 3.0.2)
|
30
|
+
tzinfo (~> 0.3.29)
|
31
|
+
activeresource (3.2.3)
|
32
|
+
activemodel (= 3.2.3)
|
33
|
+
activesupport (= 3.2.3)
|
34
|
+
activesupport (3.2.3)
|
35
|
+
i18n (~> 0.6)
|
36
|
+
multi_json (~> 1.0)
|
37
|
+
arel (3.0.2)
|
38
|
+
builder (3.0.0)
|
39
|
+
erubis (2.7.0)
|
40
|
+
hike (1.2.1)
|
41
|
+
i18n (0.6.0)
|
42
|
+
journey (1.0.3)
|
43
|
+
json (1.6.6)
|
44
|
+
mail (2.4.4)
|
44
45
|
i18n (>= 0.4.0)
|
45
46
|
mime-types (~> 1.16)
|
46
47
|
treetop (~> 1.4.8)
|
47
|
-
mime-types (1.
|
48
|
-
|
49
|
-
|
50
|
-
rack
|
51
|
-
|
52
|
-
|
48
|
+
mime-types (1.18)
|
49
|
+
multi_json (1.2.0)
|
50
|
+
polyglot (0.3.3)
|
51
|
+
rack (1.4.1)
|
52
|
+
rack-cache (1.2)
|
53
|
+
rack (>= 0.4)
|
54
|
+
rack-ssl (1.3.2)
|
55
|
+
rack
|
56
|
+
rack-test (0.6.1)
|
53
57
|
rack (>= 1.0)
|
54
|
-
rails (3.
|
55
|
-
actionmailer (= 3.
|
56
|
-
actionpack (= 3.
|
57
|
-
activerecord (= 3.
|
58
|
-
activeresource (= 3.
|
59
|
-
activesupport (= 3.
|
58
|
+
rails (3.2.3)
|
59
|
+
actionmailer (= 3.2.3)
|
60
|
+
actionpack (= 3.2.3)
|
61
|
+
activerecord (= 3.2.3)
|
62
|
+
activeresource (= 3.2.3)
|
63
|
+
activesupport (= 3.2.3)
|
60
64
|
bundler (~> 1.0)
|
61
|
-
railties (= 3.
|
62
|
-
railties (3.
|
63
|
-
actionpack (= 3.
|
64
|
-
activesupport (= 3.
|
65
|
+
railties (= 3.2.3)
|
66
|
+
railties (3.2.3)
|
67
|
+
actionpack (= 3.2.3)
|
68
|
+
activesupport (= 3.2.3)
|
69
|
+
rack-ssl (~> 1.3.2)
|
65
70
|
rake (>= 0.8.7)
|
66
71
|
rdoc (~> 3.4)
|
67
|
-
thor (~> 0.14.
|
68
|
-
rake (0.9.2)
|
69
|
-
rdoc (3.
|
70
|
-
|
72
|
+
thor (~> 0.14.6)
|
73
|
+
rake (0.9.2.2)
|
74
|
+
rdoc (3.12)
|
75
|
+
json (~> 1.4)
|
76
|
+
sprockets (2.1.2)
|
77
|
+
hike (~> 1.2)
|
78
|
+
rack (~> 1.0)
|
79
|
+
tilt (~> 1.1, != 1.3.0)
|
80
|
+
sqlite3 (1.3.5)
|
71
81
|
thor (0.14.6)
|
82
|
+
tilt (1.3.3)
|
72
83
|
treetop (1.4.10)
|
73
84
|
polyglot
|
74
85
|
polyglot (>= 0.3.1)
|
75
|
-
tzinfo (0.3.
|
86
|
+
tzinfo (0.3.32)
|
76
87
|
|
77
88
|
PLATFORMS
|
78
89
|
ruby
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
Exception Notifier Plugin for Rails
|
1
|
+
Exception Notifier Plugin for Rails  [](http://travis-ci.org/smartinez87/exception_notification)
|
2
2
|
====
|
3
3
|
|
4
4
|
The Exception Notifier plugin provides a mailer object and a default set of
|
@@ -12,72 +12,178 @@ application. The plugin is configurable, allowing programmers to specify:
|
|
12
12
|
The email includes information about the current request, session, and
|
13
13
|
environment, and also gives a backtrace of the exception.
|
14
14
|
|
15
|
+
There's a great [Railscast about Exception Notifications](http://railscasts.com/episodes/104-exception-notifications-revised)
|
16
|
+
you can see that may help you getting started.
|
17
|
+
|
15
18
|
Installation
|
16
19
|
---
|
17
20
|
|
18
21
|
You can use the latest ExceptionNotification gem with Rails 3, by adding
|
19
22
|
the following line in your Gemfile
|
20
23
|
|
21
|
-
|
24
|
+
```ruby
|
25
|
+
gem 'exception_notification'
|
26
|
+
```
|
22
27
|
|
23
28
|
As of Rails 3 ExceptionNotification is used as a rack middleware, so you can
|
24
29
|
configure its options on your config.ru file, or in the environment you
|
25
30
|
want it to run. In most cases you would want ExceptionNotification to
|
26
31
|
run on production. You can make it work by
|
27
32
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
```ruby
|
34
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
35
|
+
:email_prefix => "[Whatever] ",
|
36
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
37
|
+
:exception_recipients => %w{exceptions@example.com}
|
38
|
+
```
|
32
39
|
|
33
40
|
Customization
|
34
41
|
---
|
35
42
|
|
43
|
+
### Sections
|
44
|
+
|
36
45
|
By default, the notification email includes four parts: request, session,
|
37
46
|
environment, and backtrace (in that order). You can customize how each of those
|
38
47
|
sections are rendered by placing a partial named for that part in your
|
39
48
|
app/views/exception_notifier directory (e.g., _session.rhtml). Each partial has
|
40
49
|
access to the following variables:
|
41
50
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
51
|
+
```ruby
|
52
|
+
@controller # the controller that caused the error
|
53
|
+
@request # the current request object
|
54
|
+
@exception # the exception that was raised
|
55
|
+
@backtrace # a sanitized version of the exception's backtrace
|
56
|
+
@data # a hash of optional data values that were passed to the notifier
|
57
|
+
@sections # the array of sections to include in the email
|
58
|
+
```
|
59
|
+
|
60
|
+
Background views will not have access to @controller and @request.
|
48
61
|
|
49
62
|
You can reorder the sections, or exclude sections completely, by altering the
|
50
63
|
ExceptionNotifier.sections variable. You can even add new sections that
|
51
64
|
describe application-specific data--just add the section's name to the list
|
52
|
-
(wherever you'd like), and define the corresponding partial.
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
65
|
+
(wherever you'd like), and define the corresponding partial.
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
#Example with two new added sections
|
69
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
70
|
+
:email_prefix => "[Whatever] ",
|
71
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
72
|
+
:exception_recipients => %w{exceptions@example.com},
|
73
|
+
:sections => %w{my_section1 my_section2} + ExceptionNotifier::Notifier.default_sections
|
74
|
+
```
|
60
75
|
|
61
76
|
If your new section requires information that isn't available by default, make sure
|
62
77
|
it is made available to the email using the exception_data macro:
|
63
78
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
...
|
79
|
+
```ruby
|
80
|
+
class ApplicationController < ActionController::Base
|
81
|
+
before_filter :log_additional_data
|
82
|
+
...
|
83
|
+
protected
|
84
|
+
def log_additional_data
|
85
|
+
request.env["exception_notifier.exception_data"] = {
|
86
|
+
:document => @document,
|
87
|
+
:person => @person
|
88
|
+
}
|
75
89
|
end
|
90
|
+
...
|
91
|
+
end
|
92
|
+
```
|
76
93
|
|
77
94
|
In the above case, @document and @person would be made available to the email
|
78
95
|
renderer, allowing your new section(s) to access and display them. See the
|
79
96
|
existing sections defined by the plugin for examples of how to write your own.
|
80
97
|
|
98
|
+
You may want to include different sections for background notifications:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
#Example with two new added sections
|
102
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
103
|
+
:email_prefix => "[Whatever] ",
|
104
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
105
|
+
:exception_recipients => %w{exceptions@example.com},
|
106
|
+
:background_sections => %w{my_section1 my_section2} + ExceptionNotifier::Notifier.default_background_sections
|
107
|
+
```
|
108
|
+
|
109
|
+
By default, the backtrace and data sections are included in background
|
110
|
+
notifications.
|
111
|
+
|
112
|
+
### Ignore Exceptions
|
113
|
+
|
114
|
+
You can choose to ignore certain exceptions, which will make
|
115
|
+
ExceptionNotifier avoid sending notifications for those specified.
|
116
|
+
There are three ways of specifying which exceptions to ignore:
|
117
|
+
|
118
|
+
- `:ignore_exceptions` - By exception class (i.e. ignore RecordNotFound ones)
|
119
|
+
|
120
|
+
- `:ignore_crawlers` - From crawler (i.e. ignore ones originated by Googlebot)
|
121
|
+
|
122
|
+
- `:ignore_if` - Custom (i.e. ignore exceptions that satisfy some condition)
|
123
|
+
|
124
|
+
---
|
125
|
+
|
126
|
+
* _:ignore_exceptions_
|
127
|
+
|
128
|
+
Ignore specified exception types.
|
129
|
+
To achieve that, you should use the _:ignore_exceptions_ option, like this:
|
130
|
+
|
131
|
+
```ruby
|
132
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
133
|
+
:email_prefix => "[Whatever] ",
|
134
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
135
|
+
:exception_recipients => %w{exceptions@example.com},
|
136
|
+
:ignore_exceptions => ['ActionView::TemplateError'] + ExceptionNotifier.default_ignore_exceptions
|
137
|
+
```
|
138
|
+
|
139
|
+
The above will make ExceptionNotifier ignore a *TemplateError*
|
140
|
+
exception, plus the ones ignored by default.
|
141
|
+
By default, ExceptionNotifier ignores _ActiveRecord::RecordNotFound_,
|
142
|
+
_AbstractController::ActionNotFound_ and
|
143
|
+
_ActionController::RountingError_.
|
144
|
+
|
145
|
+
* _:ignore_crawlers_
|
146
|
+
|
147
|
+
In some cases you may want to avoid getting notifications from exceptions
|
148
|
+
made by crawlers. Using _:ignore_crawlers_ option like this,
|
149
|
+
|
150
|
+
```ruby
|
151
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
152
|
+
:email_prefix => "[Whatever] ",
|
153
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
154
|
+
:exception_recipients => %w{exceptions@example.com},
|
155
|
+
:ignore_crawlers => %w{Googlebot bingbot}
|
156
|
+
```
|
157
|
+
|
158
|
+
will prevent sending those unwanted notifications.
|
159
|
+
|
160
|
+
* _:ignore_if_
|
161
|
+
|
162
|
+
Last but not least, you can ignore exceptions based on a condition, by
|
163
|
+
|
164
|
+
```ruby
|
165
|
+
Whatever::Application.config.middleware.use ExceptionNotifier,
|
166
|
+
:email_prefix => "[Whatever] ",
|
167
|
+
:sender_address => %{"notifier" <notifier@example.com>},
|
168
|
+
:exception_recipients => %w{exceptions@example.com},
|
169
|
+
:ignore_if => lambda { |env, e| e.message =~ /^Couldn't find Page with ID=/ }
|
170
|
+
```
|
171
|
+
|
172
|
+
You can make use of both the environment and the exception inside the lambda to decide wether to
|
173
|
+
avoid or not sending the notification.
|
174
|
+
|
175
|
+
### Verbose
|
176
|
+
|
177
|
+
You can also choose to exclude the exception message from the subject, which is included by default.
|
178
|
+
Use _:verbose_subject => false_ to exclude it.
|
179
|
+
|
180
|
+
### Normalize subject
|
181
|
+
|
182
|
+
You can also choose to remove numbers from subject so they thread as a single one.
|
183
|
+
This is disabled by default.
|
184
|
+
Use _:normalize_subject => true_ to enable it.
|
185
|
+
|
186
|
+
|
81
187
|
Background Notifications
|
82
188
|
---
|
83
189
|
|
@@ -85,11 +191,26 @@ If you want to send notifications from a background process like
|
|
85
191
|
DelayedJob, you should use the background_exception_notification method
|
86
192
|
like this:
|
87
193
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
194
|
+
```ruby
|
195
|
+
begin
|
196
|
+
some code...
|
197
|
+
rescue => e
|
198
|
+
ExceptionNotifier::Notifier.background_exception_notification(e)
|
199
|
+
end
|
200
|
+
```
|
201
|
+
|
202
|
+
You can include information about the background process that created
|
203
|
+
the error by including a data parameter:
|
204
|
+
|
205
|
+
```ruby
|
206
|
+
begin
|
207
|
+
some code...
|
208
|
+
rescue => exception
|
209
|
+
ExceptionNotifier::Notifier.background_exception_notification(exception,
|
210
|
+
:data => {:worker => worker.to_s, :queue => queue, :payload => payload})
|
211
|
+
end
|
212
|
+
```
|
213
|
+
|
93
214
|
|
94
215
|
Manually notify of exception
|
95
216
|
---
|
@@ -97,13 +218,16 @@ Manually notify of exception
|
|
97
218
|
If your controller action manually handles an error, the notifier will never be
|
98
219
|
run. To manually notify of an error you can do something like the following:
|
99
220
|
|
100
|
-
|
221
|
+
```ruby
|
222
|
+
rescue_from Exception, :with => :server_error
|
101
223
|
|
102
|
-
|
103
|
-
|
224
|
+
def server_error(exception)
|
225
|
+
# Whatever code that handles the exception
|
104
226
|
|
105
|
-
|
106
|
-
|
227
|
+
ExceptionNotifier::Notifier.exception_notification(request.env, exception,
|
228
|
+
:data => {:message => "was doing something wrong"}).deliver
|
229
|
+
end
|
230
|
+
```
|
107
231
|
|
108
232
|
Notification
|
109
233
|
---
|
@@ -111,14 +235,32 @@ Notification
|
|
111
235
|
After an exception notification has been delivered the rack environment variable
|
112
236
|
'exception_notifier.delivered' will be set to +true+.
|
113
237
|
|
114
|
-
|
238
|
+
Versions
|
115
239
|
---
|
116
240
|
|
117
|
-
|
118
|
-
|
241
|
+
NOTE: Master branch is currently set for v2.6.0
|
242
|
+
|
243
|
+
For v2.5.2, see this tag:
|
244
|
+
|
245
|
+
<a href="http://github.com/smartinez87/exception_notification/tree/v2.5.2">http://github.com/smartinez87/exception_notification/tree/v2.5.2</a>
|
246
|
+
|
247
|
+
For v2.5.0, see tag:
|
248
|
+
|
249
|
+
<a href="http://github.com/smartinez87/exception_notification/tree/v2.5.0">http://github.com/smartinez87/exception_notification/tree/v2.5.0</a>
|
250
|
+
|
251
|
+
For v2.4.1, see tag:
|
252
|
+
|
253
|
+
<a href="http://github.com/smartinez87/exception_notification/tree/v2.4.1">http://github.com/smartinez87/exception_notification/tree/v2.4.1</a>
|
254
|
+
|
255
|
+
For v2.4.0, see tag:
|
256
|
+
|
257
|
+
<a href="http://github.com/smartinez87/exception_notification/tree/v2.4.0">http://github.com/smartinez87/exception_notification/tree/v2.4.0</a>
|
258
|
+
|
259
|
+
If you are running Rails 2.3 then see the branch for that:
|
260
|
+
|
119
261
|
<a href="http://github.com/smartinez87/exception_notification/tree/2-3-stable">http://github.com/smartinez87/exception_notification/tree/2-3-stable</a>
|
120
262
|
|
121
|
-
If you are running pre-rack Rails then see this tag:
|
263
|
+
If you are running pre-rack Rails then see this tag:
|
122
264
|
|
123
265
|
<a href="http://github.com/smartinez87/exception_notification/tree/pre-2-3">http://github.com/smartinez87/exception_notification/tree/pre-2-3</a>
|
124
266
|
|
@@ -127,4 +269,4 @@ Support and tickets
|
|
127
269
|
|
128
270
|
<a href="https://github.com/smartinez87/exception_notification/issues">https://github.com/smartinez87/exception_notification/issues</a>
|
129
271
|
|
130
|
-
Copyright (c) 2005 Jamis Buck, released under the MIT license
|
272
|
+
Copyright (c) 2005 Jamis Buck, released under the MIT license: <a href="http://www.opensource.org/licenses/MIT">http://www.opensource.org/licenses/MIT</a>
|
@@ -1,9 +1,10 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = 'exception_notification'
|
3
|
-
s.version = '2.
|
3
|
+
s.version = '2.6.0.rc1'
|
4
4
|
s.authors = ["Jamis Buck", "Josh Peek"]
|
5
|
-
s.date = %q{
|
5
|
+
s.date = %q{2012-04-05}
|
6
6
|
s.summary = "Exception notification by email for Rails apps"
|
7
|
+
s.homepage = "https://github.com/smartinez87/exception_notification"
|
7
8
|
s.email = "smartinez87@gmail.com"
|
8
9
|
|
9
10
|
s.files = `git ls-files`.split("\n")
|
data/lib/exception_notifier.rb
CHANGED
@@ -4,12 +4,16 @@ require 'exception_notifier/notifier'
|
|
4
4
|
class ExceptionNotifier
|
5
5
|
def self.default_ignore_exceptions
|
6
6
|
[].tap do |exceptions|
|
7
|
-
exceptions <<
|
8
|
-
exceptions <<
|
9
|
-
exceptions <<
|
7
|
+
exceptions << 'ActiveRecord::RecordNotFound'
|
8
|
+
exceptions << 'AbstractController::ActionNotFound'
|
9
|
+
exceptions << 'ActionController::RoutingError'
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
def self.default_ignore_crawlers
|
14
|
+
[]
|
15
|
+
end
|
16
|
+
|
13
17
|
def initialize(app, options = {})
|
14
18
|
@app, @options = app, options
|
15
19
|
|
@@ -17,8 +21,13 @@ class ExceptionNotifier
|
|
17
21
|
Notifier.default_exception_recipients = @options[:exception_recipients]
|
18
22
|
Notifier.default_email_prefix = @options[:email_prefix]
|
19
23
|
Notifier.default_sections = @options[:sections]
|
24
|
+
Notifier.default_background_sections = @options[:background_sections]
|
25
|
+
Notifier.default_verbose_subject = @options[:verbose_subject]
|
26
|
+
Notifier.default_normalize_subject = @options[:normalize_subject]
|
20
27
|
|
21
28
|
@options[:ignore_exceptions] ||= self.class.default_ignore_exceptions
|
29
|
+
@options[:ignore_crawlers] ||= self.class.default_ignore_crawlers
|
30
|
+
@options[:ignore_if] ||= lambda { |env, e| false }
|
22
31
|
end
|
23
32
|
|
24
33
|
def call(env)
|
@@ -27,11 +36,32 @@ class ExceptionNotifier
|
|
27
36
|
options = (env['exception_notifier.options'] ||= Notifier.default_options)
|
28
37
|
options.reverse_merge!(@options)
|
29
38
|
|
30
|
-
unless
|
39
|
+
unless ignored_exception(options[:ignore_exceptions], exception) ||
|
40
|
+
from_crawler(options[:ignore_crawlers], env['HTTP_USER_AGENT']) ||
|
41
|
+
conditionally_ignored(options[:ignore_if], env, exception)
|
31
42
|
Notifier.exception_notification(env, exception).deliver
|
32
43
|
env['exception_notifier.delivered'] = true
|
33
44
|
end
|
34
45
|
|
35
46
|
raise exception
|
36
47
|
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def ignored_exception(ignore_array, exception)
|
52
|
+
Array.wrap(ignore_array).map(&:to_s).include?(exception.class.name)
|
53
|
+
end
|
54
|
+
|
55
|
+
def from_crawler(ignore_array, agent)
|
56
|
+
ignore_array.each do |crawler|
|
57
|
+
return true if (agent =~ Regexp.new(crawler))
|
58
|
+
end unless ignore_array.blank?
|
59
|
+
false
|
60
|
+
end
|
61
|
+
|
62
|
+
def conditionally_ignored(ignore_proc, env, exception)
|
63
|
+
ignore_proc.call(env, exception)
|
64
|
+
rescue Exception => ex
|
65
|
+
false
|
66
|
+
end
|
37
67
|
end
|
@@ -6,7 +6,6 @@ class ExceptionNotifier
|
|
6
6
|
self.mailer_name = 'exception_notifier'
|
7
7
|
|
8
8
|
#Append application view path to the ExceptionNotifier lookup context.
|
9
|
-
self.append_view_path Rails.root.nil? ? "app/views" : "#{Rails.root}/app/views" if defined?(Rails)
|
10
9
|
self.append_view_path "#{File.dirname(__FILE__)}/views"
|
11
10
|
|
12
11
|
class << self
|
@@ -14,6 +13,9 @@ class ExceptionNotifier
|
|
14
13
|
attr_writer :default_exception_recipients
|
15
14
|
attr_writer :default_email_prefix
|
16
15
|
attr_writer :default_sections
|
16
|
+
attr_writer :default_background_sections
|
17
|
+
attr_writer :default_verbose_subject
|
18
|
+
attr_writer :default_normalize_subject
|
17
19
|
|
18
20
|
def default_sender_address
|
19
21
|
@default_sender_address || %("Exception Notifier" <exception.notifier@default.com>)
|
@@ -31,11 +33,30 @@ class ExceptionNotifier
|
|
31
33
|
@default_sections || %w(request session environment backtrace)
|
32
34
|
end
|
33
35
|
|
36
|
+
def default_background_sections
|
37
|
+
@default_background_sections || %w(backtrace data)
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_verbose_subject
|
41
|
+
@default_verbose_subject.nil? || @default_verbose_subject
|
42
|
+
end
|
43
|
+
|
44
|
+
def default_normalize_subject
|
45
|
+
@default_normalize_prefix || false
|
46
|
+
end
|
47
|
+
|
34
48
|
def default_options
|
35
49
|
{ :sender_address => default_sender_address,
|
36
50
|
:exception_recipients => default_exception_recipients,
|
37
51
|
:email_prefix => default_email_prefix,
|
38
|
-
:sections => default_sections
|
52
|
+
:sections => default_sections,
|
53
|
+
:background_sections => default_background_sections,
|
54
|
+
:verbose_subject => default_verbose_subject,
|
55
|
+
:normalize_subject => default_normalize_subject }
|
56
|
+
end
|
57
|
+
|
58
|
+
def normalize_digits(string)
|
59
|
+
string.gsub(/[0-9]+/, 'N')
|
39
60
|
end
|
40
61
|
end
|
41
62
|
|
@@ -44,37 +65,41 @@ class ExceptionNotifier
|
|
44
65
|
end
|
45
66
|
end
|
46
67
|
|
47
|
-
def exception_notification(env, exception)
|
68
|
+
def exception_notification(env, exception, options={})
|
69
|
+
self.append_view_path Rails.root.nil? ? "app/views" : "#{Rails.root}/app/views" if defined?(Rails)
|
70
|
+
|
48
71
|
@env = env
|
49
72
|
@exception = exception
|
50
73
|
@options = (env['exception_notifier.options'] || {}).reverse_merge(self.class.default_options)
|
51
74
|
@kontroller = env['action_controller.instance'] || MissingController.new
|
52
75
|
@request = ActionDispatch::Request.new(env)
|
53
|
-
@backtrace = clean_backtrace(exception)
|
76
|
+
@backtrace = exception.backtrace ? clean_backtrace(exception) : []
|
54
77
|
@sections = @options[:sections]
|
55
|
-
data
|
78
|
+
@data = (env['exception_notifier.exception_data'] || {}).merge(options[:data] || {})
|
79
|
+
@sections = @sections + %w(data) unless @data.empty?
|
56
80
|
|
57
|
-
data.each do |name, value|
|
81
|
+
@data.each do |name, value|
|
58
82
|
instance_variable_set("@#{name}", value)
|
59
83
|
end
|
60
|
-
|
61
|
-
prefix = "#{@options[:email_prefix]}#{@kontroller.controller_name}##{@kontroller.action_name}"
|
62
|
-
subject = "#{prefix} (#{@exception.class}) #{@exception.message.inspect}"
|
63
|
-
subject = subject.length > 120 ? subject[0...120] + "..." : subject
|
84
|
+
subject = compose_subject(exception, @kontroller)
|
64
85
|
|
65
86
|
mail(:to => @options[:exception_recipients], :from => @options[:sender_address], :subject => subject) do |format|
|
66
87
|
format.text { render "#{mailer_name}/exception_notification" }
|
67
88
|
end
|
68
89
|
end
|
69
90
|
|
70
|
-
def background_exception_notification(exception)
|
91
|
+
def background_exception_notification(exception, options={})
|
71
92
|
if @notifier = Rails.application.config.middleware.detect{ |x| x.klass == ExceptionNotifier }
|
72
|
-
@options
|
73
|
-
subject = "#{@options[:email_prefix]} (#{exception.class}) #{exception.message.inspect}"
|
74
|
-
|
93
|
+
@options = (@notifier.args.first || {}).reverse_merge(self.class.default_options)
|
75
94
|
@exception = exception
|
76
95
|
@backtrace = exception.backtrace || []
|
77
|
-
@sections =
|
96
|
+
@sections = @options[:background_sections]
|
97
|
+
@data = options[:data] || {}
|
98
|
+
|
99
|
+
@data.each do |name, value|
|
100
|
+
instance_variable_set("@#{name}", value)
|
101
|
+
end
|
102
|
+
subject = compose_subject(exception)
|
78
103
|
|
79
104
|
mail(:to => @options[:exception_recipients], :from => @options[:sender_address], :subject => subject) do |format|
|
80
105
|
format.text { render "#{mailer_name}/background_exception_notification" }
|
@@ -84,6 +109,15 @@ class ExceptionNotifier
|
|
84
109
|
|
85
110
|
private
|
86
111
|
|
112
|
+
def compose_subject(exception, kontroller=nil)
|
113
|
+
subject = "#{@options[:email_prefix]}"
|
114
|
+
subject << "#{kontroller.controller_name}##{kontroller.action_name}" if kontroller
|
115
|
+
subject << " (#{exception.class})"
|
116
|
+
subject << " #{exception.message.inspect}" if @options[:verbose_subject]
|
117
|
+
subject = normalize_digits(subject) if @options[:normalize_subject]
|
118
|
+
subject.length > 120 ? subject[0...120] + "..." : subject
|
119
|
+
end
|
120
|
+
|
87
121
|
def clean_backtrace(exception)
|
88
122
|
if Rails.respond_to?(:backtrace_cleaner)
|
89
123
|
Rails.backtrace_cleaner.send(:filter, exception.backtrace)
|
@@ -0,0 +1 @@
|
|
1
|
+
* data: <%= raw PP.pp(@data, "") %>
|
@@ -1,8 +1,8 @@
|
|
1
1
|
<% filtered_env = @request.filtered_env -%>
|
2
|
-
<% max = filtered_env.keys.max { |a, b| a.length <=> b.length } -%>
|
3
|
-
<% filtered_env.keys.sort.each do |key| -%>
|
2
|
+
<% max = filtered_env.keys.map(&:to_s).max { |a, b| a.length <=> b.length } -%>
|
3
|
+
<% filtered_env.keys.map(&:to_s).sort.each do |key| -%>
|
4
4
|
* <%= raw("%-*s: %s" % [max.length, key, inspect_object(filtered_env[key])]) %>
|
5
5
|
<% end -%>
|
6
6
|
|
7
7
|
* Process: <%= raw $$ %>
|
8
|
-
* Server : <%= raw `hostname
|
8
|
+
* Server : <%= raw `hostname`.chomp %>
|
@@ -1,2 +1,2 @@
|
|
1
|
-
* session id: <%= @request.ssl? ? "[FILTERED]" : (raw @request.session['session_id'].inspect.html_safe) %>
|
1
|
+
* session id: <%= @request.ssl? ? "[FILTERED]" : (raw (@request.session['session_id'] || @request.env["rack.session.options"][:id]).inspect.html_safe) %>
|
2
2
|
* data: <%= raw PP.pp(@request.session, "") %>
|
@@ -3,11 +3,22 @@ A <%= @exception.class %> occurred in <%= @kontroller.controller_name %>#<%= @ko
|
|
3
3
|
<%= raw @exception.message %>
|
4
4
|
<%= raw @backtrace.first %>
|
5
5
|
|
6
|
-
<%
|
7
|
-
|
8
|
-
|
6
|
+
<%
|
7
|
+
sections = @sections.map do |section|
|
8
|
+
begin
|
9
|
+
summary = render(section).strip
|
10
|
+
unless summary.blank?
|
11
|
+
title = render("title", :title => section).strip
|
12
|
+
"#{title}\n\n#{summary.gsub(/^/, " ")}\n\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue Exception => e
|
9
16
|
title = render("title", :title => section).strip
|
10
|
-
"
|
17
|
+
summary = ["ERROR: Failed to generate exception summary:", [e.class.to_s, e.message].join(": "), e.backtrace && e.backtrace.join("\n")].compact.join("\n\n")
|
18
|
+
|
19
|
+
[title, summary.gsub(/^/, " "), nil].join("\n\n")
|
11
20
|
end
|
12
|
-
end
|
21
|
+
end
|
22
|
+
%>
|
23
|
+
|
13
24
|
<%= raw sections.join %>
|
@@ -6,7 +6,9 @@ class BackgroundExceptionNotificationTest < ActiveSupport::TestCase
|
|
6
6
|
1/0
|
7
7
|
rescue => e
|
8
8
|
@exception = e
|
9
|
-
@
|
9
|
+
@time = Time.current
|
10
|
+
@mail = ExceptionNotifier::Notifier.background_exception_notification(@exception,
|
11
|
+
:data => {:job => 'DivideWorkerJob', :payload => '1/0', :message => 'My Custom Message'})
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
@@ -27,17 +29,24 @@ class BackgroundExceptionNotificationTest < ActiveSupport::TestCase
|
|
27
29
|
end
|
28
30
|
|
29
31
|
test "mail should have a descriptive subject" do
|
30
|
-
assert @mail.subject
|
32
|
+
assert @mail.subject == "[Dummy ERROR] (ZeroDivisionError) \"divided by 0\""
|
31
33
|
end
|
32
34
|
|
33
|
-
test "mail should say exception was raised in background" do
|
34
|
-
assert @mail.body.include? "A ZeroDivisionError occurred in background"
|
35
|
+
test "mail should say exception was raised in background at show timestamp" do
|
36
|
+
assert @mail.body.include? "A ZeroDivisionError occurred in background at #{@time}"
|
35
37
|
end
|
36
38
|
|
37
39
|
test "mail should contain backtrace in body" do
|
38
40
|
assert @mail.body.include? "test/background_exception_notification_test.rb:6"
|
39
41
|
end
|
40
42
|
|
43
|
+
test "mail should contain data in body" do
|
44
|
+
assert @mail.body.include? '* data:'
|
45
|
+
assert @mail.body.include? ':payload=>"1/0"'
|
46
|
+
assert @mail.body.include? ':job=>"DivideWorkerJob"'
|
47
|
+
assert @mail.body.include? "My Custom Message"
|
48
|
+
end
|
49
|
+
|
41
50
|
test "mail should not contain any attachments" do
|
42
51
|
assert @mail.attachments == []
|
43
52
|
end
|
@@ -47,7 +56,7 @@ class BackgroundExceptionNotificationTest < ActiveSupport::TestCase
|
|
47
56
|
raise ActiveRecord::RecordNotFound
|
48
57
|
rescue => e
|
49
58
|
@ignored_exception = e
|
50
|
-
unless ExceptionNotifier.default_ignore_exceptions.include?(@ignored_exception.class)
|
59
|
+
unless ExceptionNotifier.default_ignore_exceptions.include?(@ignored_exception.class.name)
|
51
60
|
@ignored_mail = ExceptionNotifier::Notifier.background_exception_notification(@ignored_exception)
|
52
61
|
end
|
53
62
|
end
|
data/test/dummy/Gemfile.lock
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
* New section for testing
|
@@ -4,7 +4,8 @@ require File.expand_path('../application', __FILE__)
|
|
4
4
|
Dummy::Application.config.middleware.use ExceptionNotifier,
|
5
5
|
:email_prefix => "[Dummy ERROR] ",
|
6
6
|
:sender_address => %{"Dummy Notifier" <dummynotifier@example.com>},
|
7
|
-
:exception_recipients => %w{dummyexceptions@example.com}
|
7
|
+
:exception_recipients => %w{dummyexceptions@example.com},
|
8
|
+
:sections => ['new_section', 'request', 'session', 'environment', 'backtrace']
|
8
9
|
|
9
10
|
# Initialize the rails application
|
10
11
|
Dummy::Application.initialize!
|
@@ -7,7 +7,7 @@ class PostsControllerTest < ActionController::TestCase
|
|
7
7
|
post :create, :post => @post.attributes
|
8
8
|
rescue => e
|
9
9
|
@exception = e
|
10
|
-
@mail = ExceptionNotifier::Notifier.exception_notification(request.env, @exception)
|
10
|
+
@mail = ExceptionNotifier::Notifier.exception_notification(request.env, @exception, {:data => {:message => 'My Custom Message'}})
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
@@ -28,13 +28,25 @@ class PostsControllerTest < ActionController::TestCase
|
|
28
28
|
end
|
29
29
|
|
30
30
|
test "mail should have a descriptive subject" do
|
31
|
-
assert @mail.subject.include? "[Dummy ERROR] # (NoMethodError)"
|
31
|
+
assert @mail.subject.include? "[Dummy ERROR] # (NoMethodError) \"undefined method `nw'"
|
32
32
|
end
|
33
33
|
|
34
34
|
test "mail should contain backtrace in body" do
|
35
35
|
assert @mail.body.include? "`method_missing'\n app/controllers/posts_controller.rb:17:in `create'\n"
|
36
36
|
end
|
37
37
|
|
38
|
+
test "mail should contain timestamp of exception in body" do
|
39
|
+
assert @mail.body.include? "Timestamp : #{Time.current}"
|
40
|
+
end
|
41
|
+
|
42
|
+
test "mail should contain the newly defined section" do
|
43
|
+
assert @mail.body.include? "* New section for testing"
|
44
|
+
end
|
45
|
+
|
46
|
+
test "mail should contain the custom message" do
|
47
|
+
assert @mail.body.include? "My Custom Message"
|
48
|
+
end
|
49
|
+
|
38
50
|
test "should filter sensible data" do
|
39
51
|
assert @mail.body.include? "secret\"=>\"[FILTERED]"
|
40
52
|
end
|
@@ -48,7 +60,7 @@ class PostsControllerTest < ActionController::TestCase
|
|
48
60
|
get :show, :id => @post.to_param + "10"
|
49
61
|
rescue => e
|
50
62
|
@ignored_exception = e
|
51
|
-
unless ExceptionNotifier.default_ignore_exceptions.include?(@ignored_exception.class)
|
63
|
+
unless ExceptionNotifier.default_ignore_exceptions.include?(@ignored_exception.class.name)
|
52
64
|
@ignored_mail = ExceptionNotifier::Notifier.exception_notification(request.env, @ignored_exception)
|
53
65
|
end
|
54
66
|
end
|
@@ -69,4 +81,87 @@ class PostsControllerTest < ActionController::TestCase
|
|
69
81
|
assert request.ssl?
|
70
82
|
assert @secured_mail.body.include? "* session id: [FILTERED]\n *"
|
71
83
|
end
|
84
|
+
|
85
|
+
test "should ignore exception if from unwanted cralwer" do
|
86
|
+
request.env['HTTP_USER_AGENT'] = "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
|
87
|
+
begin
|
88
|
+
@post = posts(:one)
|
89
|
+
post :create, :post => @post.attributes
|
90
|
+
rescue => e
|
91
|
+
@exception = e
|
92
|
+
custom_env = request.env
|
93
|
+
custom_env['exception_notifier.options'] ||= {}
|
94
|
+
custom_env['exception_notifier.options'].merge!(:ignore_crawlers => %w(Googlebot))
|
95
|
+
ignore_array = custom_env['exception_notifier.options'][:ignore_crawlers]
|
96
|
+
unless ExceptionNotifier.new(Dummy::Application, custom_env['exception_notifier.options']).send(:from_crawler, ignore_array, custom_env['HTTP_USER_AGENT'])
|
97
|
+
@ignored_mail = ExceptionNotifier::Notifier.exception_notification(custom_env, @exception)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
assert_nil @ignored_mail
|
102
|
+
end
|
103
|
+
|
104
|
+
test "should ignore exception if satisfies conditional ignore" do
|
105
|
+
request.env['IGNOREME'] = "IGNOREME"
|
106
|
+
begin
|
107
|
+
@post = posts(:one)
|
108
|
+
post :create, :post => @post.attributes
|
109
|
+
rescue => e
|
110
|
+
@exception = e
|
111
|
+
custom_env = request.env
|
112
|
+
custom_env['exception_notifier.options'] ||= {}
|
113
|
+
ignore_cond = {:ignore_if => lambda {|env, e| (env['IGNOREME'] == 'IGNOREME') && (e.message =~ /undefined method/)}}
|
114
|
+
custom_env['exception_notifier.options'].merge!(ignore_cond)
|
115
|
+
unless ExceptionNotifier.new(Dummy::Application, custom_env['exception_notifier.options']).send(:conditionally_ignored, ignore_cond[:ignore_if], custom_env, @exception)
|
116
|
+
@ignored_mail = ExceptionNotifier::Notifier.exception_notification(custom_env, @exception)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
assert_nil @ignored_mail
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
class PostsControllerTestWithoutVerboseSubject < ActionController::TestCase
|
125
|
+
tests PostsController
|
126
|
+
setup do
|
127
|
+
ExceptionNotifier::Notifier.default_verbose_subject = false
|
128
|
+
begin
|
129
|
+
@post = posts(:one)
|
130
|
+
post :create, :post => @post.attributes
|
131
|
+
rescue => e
|
132
|
+
@exception = e
|
133
|
+
@mail = ExceptionNotifier::Notifier.exception_notification(request.env, @exception)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
test "should not include exception message in subject" do
|
138
|
+
assert_equal "[ERROR] # (NoMethodError)", @mail.subject
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
class PostsControllerTestBadRequestData < ActionController::TestCase
|
143
|
+
tests PostsController
|
144
|
+
setup do
|
145
|
+
begin
|
146
|
+
# This might seem synthetic, but the point is that the data used by
|
147
|
+
# ExceptionNotification could be rendered "invalid" by e.g. a badly
|
148
|
+
# behaving middleware, and we want to test that ExceptionNotification
|
149
|
+
# still manages to send off an email in those cases.
|
150
|
+
#
|
151
|
+
# The trick here is to trigger an exception in the template used by
|
152
|
+
# ExceptionNotification. (The original test stuffed request.env with
|
153
|
+
# badly encoded strings, but that only works in Ruby 1.9+.)
|
154
|
+
request.send :instance_variable_set, :@env, {}
|
155
|
+
|
156
|
+
@post = posts(:one)
|
157
|
+
post :create, :post => @post.attributes
|
158
|
+
rescue => e
|
159
|
+
@exception = e
|
160
|
+
@mail = ExceptionNotifier::Notifier.exception_notification(request.env, @exception)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
test "should include error message in body" do
|
165
|
+
assert_match /ERROR: Failed to generate exception summary/, @mail.body.to_s
|
166
|
+
end
|
72
167
|
end
|
@@ -2,7 +2,7 @@ require 'test_helper'
|
|
2
2
|
|
3
3
|
class ExceptionNotificationTest < ActiveSupport::TestCase
|
4
4
|
test "should have default ignored exceptions" do
|
5
|
-
assert ExceptionNotifier.default_ignore_exceptions == [ActiveRecord::RecordNotFound, AbstractController::ActionNotFound, ActionController::RoutingError]
|
5
|
+
assert ExceptionNotifier.default_ignore_exceptions == ['ActiveRecord::RecordNotFound', 'AbstractController::ActionNotFound', 'ActionController::RoutingError']
|
6
6
|
end
|
7
7
|
|
8
8
|
test "should have default sender address overriden" do
|
@@ -14,6 +14,29 @@ class ExceptionNotificationTest < ActiveSupport::TestCase
|
|
14
14
|
end
|
15
15
|
|
16
16
|
test "should have default sections" do
|
17
|
-
|
17
|
+
for section in %w(request session environment backtrace)
|
18
|
+
assert ExceptionNotifier::Notifier.default_sections.include? section
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
test "should have default background sections" do
|
23
|
+
assert ExceptionNotifier::Notifier.default_background_sections == %w(backtrace data)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "should have verbose subject by default" do
|
27
|
+
assert ExceptionNotifier::Notifier.default_options[:verbose_subject] == true
|
28
|
+
end
|
29
|
+
|
30
|
+
test "should have ignored crawler by default" do
|
31
|
+
assert ExceptionNotifier.default_ignore_crawlers == []
|
32
|
+
end
|
33
|
+
|
34
|
+
test "should normalize multiple digits into one N" do
|
35
|
+
assert_equal 'N foo N bar N baz N',
|
36
|
+
ExceptionNotifier::Notifier.normalize_digits('1 foo 12 bar 123 baz 1234')
|
37
|
+
end
|
38
|
+
|
39
|
+
test "should have normalize_subject false by default" do
|
40
|
+
assert ExceptionNotifier::Notifier.default_options[:normalize_subject] == false
|
18
41
|
end
|
19
42
|
end
|
metadata
CHANGED
@@ -1,81 +1,71 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_notification
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 2
|
8
|
-
- 5
|
9
|
-
- 2
|
10
|
-
version: 2.5.2
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 2.6.0.rc1
|
5
|
+
prerelease: 6
|
11
6
|
platform: ruby
|
12
|
-
authors:
|
7
|
+
authors:
|
13
8
|
- Jamis Buck
|
14
9
|
- Josh Peek
|
15
10
|
autorequire:
|
16
11
|
bindir: bin
|
17
12
|
cert_chain: []
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
dependencies:
|
22
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2012-04-05 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
23
16
|
name: actionmailer
|
24
|
-
|
25
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
26
18
|
none: false
|
27
|
-
requirements:
|
28
|
-
- -
|
29
|
-
- !ruby/object:Gem::Version
|
30
|
-
hash: 15
|
31
|
-
segments:
|
32
|
-
- 3
|
33
|
-
- 0
|
34
|
-
- 4
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
35
22
|
version: 3.0.4
|
36
23
|
type: :runtime
|
37
|
-
version_requirements: *id001
|
38
|
-
- !ruby/object:Gem::Dependency
|
39
|
-
name: rails
|
40
24
|
prerelease: false
|
41
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: 3.0.4
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: rails
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
42
34
|
none: false
|
43
|
-
requirements:
|
44
|
-
- -
|
45
|
-
- !ruby/object:Gem::Version
|
46
|
-
hash: 15
|
47
|
-
segments:
|
48
|
-
- 3
|
49
|
-
- 0
|
50
|
-
- 4
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
51
38
|
version: 3.0.4
|
52
39
|
type: :development
|
53
|
-
version_requirements: *id002
|
54
|
-
- !ruby/object:Gem::Dependency
|
55
|
-
name: sqlite3
|
56
40
|
prerelease: false
|
57
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
42
|
none: false
|
59
|
-
requirements:
|
60
|
-
- -
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 3.0.4
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: sqlite3
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
67
54
|
version: 1.3.4
|
68
55
|
type: :development
|
69
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.3.4
|
70
63
|
description:
|
71
64
|
email: smartinez87@gmail.com
|
72
65
|
executables: []
|
73
|
-
|
74
66
|
extensions: []
|
75
|
-
|
76
67
|
extra_rdoc_files: []
|
77
|
-
|
78
|
-
files:
|
68
|
+
files:
|
79
69
|
- .gemtest
|
80
70
|
- Gemfile
|
81
71
|
- Gemfile.lock
|
@@ -86,6 +76,7 @@ files:
|
|
86
76
|
- lib/exception_notifier.rb
|
87
77
|
- lib/exception_notifier/notifier.rb
|
88
78
|
- lib/exception_notifier/views/exception_notifier/_backtrace.text.erb
|
79
|
+
- lib/exception_notifier/views/exception_notifier/_data.text.erb
|
89
80
|
- lib/exception_notifier/views/exception_notifier/_environment.text.erb
|
90
81
|
- lib/exception_notifier/views/exception_notifier/_request.text.erb
|
91
82
|
- lib/exception_notifier/views/exception_notifier/_session.text.erb
|
@@ -102,6 +93,7 @@ files:
|
|
102
93
|
- test/dummy/app/helpers/application_helper.rb
|
103
94
|
- test/dummy/app/helpers/posts_helper.rb
|
104
95
|
- test/dummy/app/models/post.rb
|
96
|
+
- test/dummy/app/views/exception_notifier/_new_section.text.erb
|
105
97
|
- test/dummy/app/views/layouts/application.html.erb
|
106
98
|
- test/dummy/app/views/posts/_form.html.erb
|
107
99
|
- test/dummy/app/views/posts/new.html.erb
|
@@ -146,41 +138,31 @@ files:
|
|
146
138
|
- test/dummy/test/test_helper.rb
|
147
139
|
- test/exception_notification_test.rb
|
148
140
|
- test/test_helper.rb
|
149
|
-
|
150
|
-
homepage:
|
141
|
+
homepage: https://github.com/smartinez87/exception_notification
|
151
142
|
licenses: []
|
152
|
-
|
153
143
|
post_install_message:
|
154
144
|
rdoc_options: []
|
155
|
-
|
156
|
-
require_paths:
|
145
|
+
require_paths:
|
157
146
|
- lib
|
158
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
148
|
none: false
|
160
|
-
requirements:
|
161
|
-
- -
|
162
|
-
- !ruby/object:Gem::Version
|
163
|
-
|
164
|
-
|
165
|
-
- 0
|
166
|
-
version: "0"
|
167
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
154
|
none: false
|
169
|
-
requirements:
|
170
|
-
- -
|
171
|
-
- !ruby/object:Gem::Version
|
172
|
-
|
173
|
-
segments:
|
174
|
-
- 0
|
175
|
-
version: "0"
|
155
|
+
requirements:
|
156
|
+
- - ! '>'
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: 1.3.1
|
176
159
|
requirements: []
|
177
|
-
|
178
160
|
rubyforge_project:
|
179
|
-
rubygems_version: 1.
|
161
|
+
rubygems_version: 1.8.21
|
180
162
|
signing_key:
|
181
163
|
specification_version: 3
|
182
164
|
summary: Exception notification by email for Rails apps
|
183
|
-
test_files:
|
165
|
+
test_files:
|
184
166
|
- test/background_exception_notification_test.rb
|
185
167
|
- test/dummy/.gitignore
|
186
168
|
- test/dummy/Gemfile
|
@@ -191,6 +173,7 @@ test_files:
|
|
191
173
|
- test/dummy/app/helpers/application_helper.rb
|
192
174
|
- test/dummy/app/helpers/posts_helper.rb
|
193
175
|
- test/dummy/app/models/post.rb
|
176
|
+
- test/dummy/app/views/exception_notifier/_new_section.text.erb
|
194
177
|
- test/dummy/app/views/layouts/application.html.erb
|
195
178
|
- test/dummy/app/views/posts/_form.html.erb
|
196
179
|
- test/dummy/app/views/posts/new.html.erb
|