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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c65dc23c6e47e44540d172c0499734b0788b9a22dc689b58e7c558fca89efefd
4
- data.tar.gz: 286902eea5d066ba92dd66aeab81114688dd6b71ca0a0b484bf4a5cbee2cc5f3
3
+ metadata.gz: 2fb501bfc67399400c0d73e8d6df68fb8a20c25f6e12ef2dbc0507afda20aa93
4
+ data.tar.gz: 7f9af95d0edc69281d63c6b9cffb3ae259dec67bda2ce7e7901d6cb5bda371b8
5
5
  SHA512:
6
- metadata.gz: 9f51b701f9d13e33cb37a477b1eedeb799ccfcdb9b45dd13cd96fa1d47f80c66bbea9fad6293ed51488991c9b3073d80844cd3651c26dbba904693d948b5938a
7
- data.tar.gz: feb499e25bdb858705bc9eb5a28d4ece1603028633f7fd201859bc26da4ae24b7194dd5f9e3241f2f31b01f160c1dfe8ee60563f65972d6879769bcec24324ea
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 }, current_user: user)
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
- 2. Add it to your workspace.
106
- 3. Add one or more webhooks linked to the channels you want to receive the notifications.
107
- 4. Set the webhook urls in the `exception_hunter` initializer.
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
- 6. Add the code below to the environment config file where you are using ExceptionHunter with the correct server url.
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
@@ -11,7 +11,8 @@ module ExceptionHunter
11
11
  end
12
12
 
13
13
  def self.format_occurrence_day(day)
14
- day.to_date.strftime('%A, %B %d')
14
+ date = day.to_date
15
+ date == Date.yesterday ? 'Yesterday' : date.strftime('%A, %B %d')
15
16
  end
16
17
 
17
18
  def show_for_day?(day)
@@ -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
- <% yesterday_errors = errors.select { |error| error.show_for_day?(Date.yesterday) } %>
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
@@ -31,6 +31,7 @@ module ExceptionHunter
31
31
  return unless should_track?(job.attempts)
32
32
 
33
33
  ErrorCreator.call(
34
+ async_logging: false,
34
35
  tag: ErrorCreator::WORKER_TAG,
35
36
  class_name: exception.class.to_s,
36
37
  message: exception.message,
@@ -28,6 +28,7 @@ module ExceptionHunter
28
28
  return unless should_track?(context)
29
29
 
30
30
  ErrorCreator.call(
31
+ async_logging: false,
31
32
  tag: ErrorCreator::WORKER_TAG,
32
33
  class_name: exception.class.to_s,
33
34
  message: exception.message,
@@ -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
- nil
53
+ def open_transactions?
54
+ ActiveRecord::Base.connection.open_transactions.positive?
33
55
  end
34
56
  end
35
57
  end
@@ -1,3 +1,3 @@
1
1
  module ExceptionHunter
2
- VERSION = '1.0.2'.freeze
2
+ VERSION = '1.1.0'.freeze
3
3
  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.2
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-02-03 00:00:00.000000000 Z
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