exception_hunter 1.0.2 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +21 -7
- data/app/jobs/exception_hunter/async_logging_job.rb +13 -0
- data/app/presenters/exception_hunter/error_group_presenter.rb +2 -1
- data/app/views/exception_hunter/errors/_last_7_days_errors_table.erb +1 -5
- data/lib/exception_hunter/config.rb +3 -0
- data/lib/exception_hunter/error_creator.rb +14 -5
- data/lib/exception_hunter/middleware/delayed_job_hunter.rb +1 -0
- data/lib/exception_hunter/middleware/sidekiq_hunter.rb +1 -0
- data/lib/exception_hunter/tracking.rb +23 -1
- data/lib/exception_hunter/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2fb501bfc67399400c0d73e8d6df68fb8a20c25f6e12ef2dbc0507afda20aa93
|
4
|
+
data.tar.gz: 7f9af95d0edc69281d63c6b9cffb3ae259dec67bda2ce7e7901d6cb5bda371b8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6170a00e2225b75eb4c7b9e8ee4278cf520df79728fe717ba5bd785136195f31fe72c417d8d794e38d63b64b528dcbc4a449fee09f2976b286542e1c69ff2dcd
|
7
|
+
data.tar.gz: b349b87bf65da803cf32044b69cfb53a81329d6a02b50dc535c6a257aaad16dd32789547eb3858d2714015322f67008efdf217e4d3f5474418ed008f19abb2d5
|
data/README.md
CHANGED
@@ -23,9 +23,10 @@ project, and MVP or something else.
|
|
23
23
|
|
24
24
|
## Docs
|
25
25
|
|
26
|
-
You can check the full documentation at [https://rootstrap.github.io/exception_hunter]().
|
26
|
+
You can check the full documentation at [https://rootstrap.github.io/exception_hunter](https://rootstrap.github.io/exception_hunter).
|
27
27
|
|
28
28
|
## Installation
|
29
|
+
|
29
30
|
Add Exception Hunter to your application's Gemfile:
|
30
31
|
|
31
32
|
```ruby
|
@@ -65,7 +66,6 @@ You can then open a `rails console` and manually track an exception to check tha
|
|
65
66
|
works `ExceptionHunter.track(StandardError.new("It works!"))`. You should now see the exception
|
66
67
|
on [http://localhost:3000/exception_hunter]().
|
67
68
|
|
68
|
-
|
69
69
|
## Stale data
|
70
70
|
|
71
71
|
You can get rid of stale errors by running the rake task to purge them:
|
@@ -89,7 +89,7 @@ when :inactive then do_something
|
|
89
89
|
when :active then do_something_else
|
90
90
|
when :banned then do_something_else_else
|
91
91
|
else
|
92
|
-
ExceptionHunter.track(ArgumentError.new('This should never happen'), custom_data: { status: current_user.status },
|
92
|
+
ExceptionHunter.track(ArgumentError.new('This should never happen'), custom_data: { status: current_user.status }, user: current_user)
|
93
93
|
end
|
94
94
|
```
|
95
95
|
|
@@ -102,9 +102,9 @@ You can configure ExceptionHunter to send a message to slack every time an error
|
|
102
102
|
You have to do the following:
|
103
103
|
|
104
104
|
1. Create a Slack app.
|
105
|
-
|
106
|
-
|
107
|
-
|
105
|
+
1. Add it to your workspace.
|
106
|
+
1. Add one or more webhooks linked to the channels you want to receive the notifications.
|
107
|
+
1. Set the webhook urls in the `exception_hunter` initializer.
|
108
108
|
|
109
109
|
```ruby
|
110
110
|
config.notifiers << {
|
@@ -122,7 +122,7 @@ config.notifiers << {
|
|
122
122
|
}
|
123
123
|
```
|
124
124
|
|
125
|
-
|
125
|
+
1. Add the code below to the environment config file where you are using ExceptionHunter with the correct server url.
|
126
126
|
|
127
127
|
```ruby
|
128
128
|
ExceptionHunter::Engine.configure do |config|
|
@@ -132,7 +132,21 @@ end
|
|
132
132
|
|
133
133
|
This uses ActiveJob to send notification in the background, so [make sure you configure](https://guides.rubyonrails.org/active_job_basics.html#setting-the-backend) it with the adapter you are using, if not notifications will be sent synchronously.
|
134
134
|
|
135
|
+
## Async Logging
|
136
|
+
|
137
|
+
You can configure ExceptionHunter to log async when an error occurs.
|
138
|
+
You have to do the following:
|
139
|
+
|
140
|
+
```ruby
|
141
|
+
config.async_logging = true;
|
142
|
+
```
|
143
|
+
|
144
|
+
This uses ActiveJob to log the error in the background, so [make sure you configure](https://guides.rubyonrails.org/active_job_basics.html#setting-the-backend) it with the adapter you are using, if not the error will be logged synchronously.
|
145
|
+
|
146
|
+
Note: Errors from jobs will still be logged synchronously to not queue a job from a job (which sound like a bad idea)
|
147
|
+
|
135
148
|
## License
|
149
|
+
|
136
150
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
137
151
|
|
138
152
|
## Credits
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module ExceptionHunter
|
2
|
+
class AsyncLoggingJob < ApplicationJob
|
3
|
+
queue_as :default
|
4
|
+
|
5
|
+
def perform(tag, error_attrs)
|
6
|
+
error_attrs = error_attrs.merge(occurred_at: Time.at(error_attrs[:occurred_at])) if error_attrs[:occurred_at]
|
7
|
+
ErrorCreator.call(async_logging: false, tag: tag, **error_attrs)
|
8
|
+
rescue Exception
|
9
|
+
# Suppress all exceptions to avoid loop as this would create a new error in EH.
|
10
|
+
false
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
<% today_errors = errors.select { |error| error.show_for_day?(Date.current) } %>
|
2
2
|
<%= render partial: 'exception_hunter/errors/error_row', collection: today_errors, as: :error %>
|
3
3
|
|
4
|
-
<%
|
5
|
-
<div class="errors-date-group">Yesterday</div>
|
6
|
-
<%= render partial: 'exception_hunter/errors/error_row', collection: yesterday_errors, as: :error %>
|
7
|
-
|
8
|
-
<% (2..6).each do |i| %>
|
4
|
+
<% (1..6).each do |i| %>
|
9
5
|
<% errors_on_day = errors.select { |error| error.show_for_day?(i.days.ago) } %>
|
10
6
|
<div class="errors-date-group"><%= ExceptionHunter::ErrorGroupPresenter.format_occurrence_day(i.days.ago) %></div>
|
11
7
|
<%= render partial: 'exception_hunter/errors/error_row', collection: errors_on_day, as: :error %>
|
@@ -17,6 +17,9 @@ module ExceptionHunter
|
|
17
17
|
# @return [Array<Hash>] configured notifiers for the application (see {ExceptionHunter::Notifiers})
|
18
18
|
cattr_accessor :notifiers, default: []
|
19
19
|
cattr_accessor :sensitive_fields, default: []
|
20
|
+
# @!attribute
|
21
|
+
# @return [Boolean] whether ExceptionHunter should log async or not
|
22
|
+
cattr_accessor :async_logging, default: false
|
20
23
|
|
21
24
|
# Returns true if there's an admin user class configured to
|
22
25
|
# authenticate against.
|
@@ -12,9 +12,22 @@ module ExceptionHunter
|
|
12
12
|
#
|
13
13
|
# @param [HTTP_TAG, WORKER_TAG, MANUAL_TAG] tag to append to the error if any
|
14
14
|
# @return [ExceptionHunter::Error, false] the error or false if it was not possible to create it
|
15
|
-
def call(tag: nil, **error_attrs)
|
15
|
+
def call(async_logging: Config.async_logging, tag: nil, **error_attrs)
|
16
16
|
return unless should_create?
|
17
17
|
|
18
|
+
if async_logging
|
19
|
+
# Time is sent in unix format and then converted to Time to avoid ActiveJob::SerializationError
|
20
|
+
::ExceptionHunter::AsyncLoggingJob.perform_later(tag, error_attrs.merge(occurred_at: Time.now.to_i))
|
21
|
+
else
|
22
|
+
create_error(tag, error_attrs)
|
23
|
+
end
|
24
|
+
rescue ActiveRecord::RecordInvalid
|
25
|
+
false
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def create_error(tag, error_attrs)
|
18
31
|
ActiveRecord::Base.transaction do
|
19
32
|
error_attrs = extract_user_data(error_attrs)
|
20
33
|
error_attrs = hide_sensitive_values(error_attrs)
|
@@ -28,12 +41,8 @@ module ExceptionHunter
|
|
28
41
|
notify(error)
|
29
42
|
error
|
30
43
|
end
|
31
|
-
rescue ActiveRecord::RecordInvalid
|
32
|
-
false
|
33
44
|
end
|
34
45
|
|
35
|
-
private
|
36
|
-
|
37
46
|
def should_create?
|
38
47
|
Config.enabled
|
39
48
|
end
|
@@ -19,6 +19,26 @@ module ExceptionHunter
|
|
19
19
|
# @param [User] user in the current session. (optional)
|
20
20
|
# @return [void]
|
21
21
|
def track(exception, custom_data: {}, user: nil)
|
22
|
+
if open_transactions?
|
23
|
+
create_error_within_new_thread(exception, custom_data, user)
|
24
|
+
else
|
25
|
+
create_error(exception, custom_data, user)
|
26
|
+
end
|
27
|
+
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def create_error_within_new_thread(exception, custom_data, user)
|
34
|
+
Thread.new {
|
35
|
+
ActiveRecord::Base.connection_pool.with_connection do
|
36
|
+
create_error(exception, custom_data, user)
|
37
|
+
end
|
38
|
+
}.join
|
39
|
+
end
|
40
|
+
|
41
|
+
def create_error(exception, custom_data, user)
|
22
42
|
ErrorCreator.call(
|
23
43
|
tag: ErrorCreator::MANUAL_TAG,
|
24
44
|
class_name: exception.class.to_s,
|
@@ -28,8 +48,10 @@ module ExceptionHunter
|
|
28
48
|
user: user,
|
29
49
|
environment_data: {}
|
30
50
|
)
|
51
|
+
end
|
31
52
|
|
32
|
-
|
53
|
+
def open_transactions?
|
54
|
+
ActiveRecord::Base.connection.open_transactions.positive?
|
33
55
|
end
|
34
56
|
end
|
35
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: exception_hunter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Bruno Vezoli
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2021-
|
12
|
+
date: 2021-07-30 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pagy
|
@@ -163,6 +163,7 @@ files:
|
|
163
163
|
- app/helpers/exception_hunter/errors_helper.rb
|
164
164
|
- app/helpers/exception_hunter/sessions_helper.rb
|
165
165
|
- app/jobs/exception_hunter/application_job.rb
|
166
|
+
- app/jobs/exception_hunter/async_logging_job.rb
|
166
167
|
- app/jobs/exception_hunter/send_notification_job.rb
|
167
168
|
- app/mailers/exception_hunter/application_mailer.rb
|
168
169
|
- app/models/exception_hunter/application_record.rb
|