exception_notification 2.5.2 → 2.6.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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 ![project status](http://stillmaintained.com/smartinez87/exception_notification.png) [![Travis](http://travis-ci.org/smartinez87/exception_notification.png)](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
|