exception_hunter 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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