solid_errors 0.3.5 → 0.4.1

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: a2eee8c990cddbb820d0e26419c5a08d163552840313b5468d15c9590d07f831
4
- data.tar.gz: 578aac9f9b1f58003b50cd1482cedbda43804e54ee1349a52fd47f79acc51f18
3
+ metadata.gz: e0d26fb72eb0854e6e37aee98b4c2df2265b98de7428e4ccabf4de6a625ef594
4
+ data.tar.gz: c7aa9a23afe14b6bcfa71433361478e1e7d36138dde44feda533db466689feb1
5
5
  SHA512:
6
- metadata.gz: 5ec9d232d8e0b622cfa099b2c2fd16232681b65ca24825411caa95cf91680da02099a0ddb6ce2901ce3857d9489cf2d0cef410aef8609f6cc54ff2ff19821afd
7
- data.tar.gz: 61a0e98f22ee56313cb7867452b0ae42945a204cb5736edec59aa429d103d4b136ba223bf28bc7d54f85bb7c00b483d2557e41473c76f38fdff915577c9004a6
6
+ metadata.gz: 9fbfa4a7f0abe945d847288a585ce8b1ed08b999634f754f5de178b6445c8a6f213593fda98b6bdb508742510242bdb091c9832b692879b5740c78a57f7219c4
7
+ data.tar.gz: 99016e0f3e47ff0ab80db55f30042b49d4c8f2233731da5d4f56547735260d88222054ed443009a474cba39831144288337536c2f036456baab93e819d7541bb
data/README.md CHANGED
@@ -66,11 +66,14 @@ There are intentionally few features; you can view and resolve errors. That’s
66
66
 
67
67
  ### Configuration
68
68
 
69
- You can configure Solid Errors via the Rails configuration object, under the `solid_errors` key. Currently, only 3 configuration options are available:
69
+ You can configure Solid Errors via the Rails configuration object, under the `solid_errors` key. Currently, 6 configuration options are available:
70
70
 
71
71
  * `connects_to` - The database configuration to use for the Solid Errors database. See [Database Configuration](#database-configuration) for more information.
72
72
  * `username` - The username to use for HTTP authentication. See [Authentication](#authentication) for more information.
73
73
  * `password` - The password to use for HTTP authentication. See [Authentication](#authentication) for more information.
74
+ * `sends_email` - Whether or not to send emails when an error occurs. See [Email notifications](#email-notifications) for more information.
75
+ * `email_from` - The email address to send a notification from. See [Email notifications](#email-notifications) for more information.
76
+ * `email_to` - The email address(es) to send a notification to. See [Email notifications](#email-notifications) for more information.
74
77
 
75
78
  #### Database Configuration
76
79
 
@@ -109,7 +112,7 @@ config.solid_errors.password = Rails.application.credentials.solid_errors.passwo
109
112
 
110
113
  Either way, if you have set a username and password, Solid Errors will use basic HTTP authentication. If you have not set a username and password, Solid Errors will not require any authentication to view the dashboard.
111
114
 
112
- If you use Devise for authenctication in your app, you can also restrict access to the dashboard by using their `authenticate` contraint in your routes file:
115
+ If you use Devise for authentication in your app, you can also restrict access to the dashboard by using their `authenticate` constraint in your routes file:
113
116
 
114
117
  ```ruby
115
118
  authenticate :user, -> (user) { user.admin? } do
@@ -117,6 +120,29 @@ authenticate :user, -> (user) { user.admin? } do
117
120
  end
118
121
  ```
119
122
 
123
+ #### Email notifications
124
+
125
+ Solid Errors _can_ send email notifications whenever an error occurs, if your application has ActionMailer already properly setup to send emails. However, in order to activate this feature you must define the email address(es) to send the notifications to. Optionally, you can also define the email address to send the notifications from (useful if your email provider only allows emails to be sent from a predefined list of addresses) or simply turn off this feature altogether.
126
+
127
+ There are two ways to configure email notifications. First, you can use environment variables:
128
+
129
+ ```ruby
130
+ ENV["SOLIDERRORS_SEND_EMAILS"] = true # defaults to true
131
+ ENV["SOLIDERRORS_EMAIL_FROM"] = "errors@myapp.com" # defaults to "solid_errors@noreply.com"
132
+ ENV["SOLIDERRORS_EMAIL_TO"] = "devs@myapp.com" # no default, must be set
133
+ ```
134
+
135
+ Second, you can set the values via the configuration object:
136
+
137
+ ```ruby
138
+ # Set authentication credentials for Solid Errors
139
+ config.solid_errors.send_emails = true
140
+ config.solid_errors.email_from = "errors@myapp.com"
141
+ config.solid_errors.email_to = "devs@myapp.com"
142
+ ```
143
+
144
+ If you have set `send_emails` to `true` and have set an `email_to` address, Solid Errors will send an email notification whenever an error occurs. If you have not set `send_emails` to `true` or have not set an `email_to` address, Solid Errors will not send any email notifications.
145
+
120
146
  ### Examples
121
147
 
122
148
  There are only two screens in the dashboard.
@@ -129,6 +155,76 @@ There are only two screens in the dashboard.
129
155
 
130
156
  ![image description](images/show-screenshot.png)
131
157
 
158
+ ### Usage with API-only Applications
159
+
160
+ If your Rails application is an API-only application (generated with the `rails new --api` command), you will need to add the following middleware to your `config/application.rb` file in order to use the dashboard UI provided by Solid Errors:
161
+
162
+ ```ruby
163
+ # /config/application.rb
164
+ config.middleware.use ActionDispatch::Cookies
165
+ config.middleware.use ActionDispatch::Session::CookieStore
166
+ config.middleware.use ActionDispatch::Flash
167
+ ```
168
+
169
+ ### Overwriting the views
170
+
171
+ You can find the views in [`app/views`](https://github.com/fractaledmind/solid_errors/tree/main/app/views).
172
+
173
+ ```bash
174
+ app/views/
175
+ ├── layouts
176
+ │   └── solid_errors
177
+ │   ├── _style.html
178
+ │   └── application.html.erb
179
+ └── solid_errors
180
+ ├── error_mailer
181
+ │   ├── error_occurred.html.erb
182
+ │   └── error_occurred.text.erb
183
+ ├── errors
184
+ │   ├── _actions.html.erb
185
+ │   ├── _error.html.erb
186
+ │   ├── _row.html.erb
187
+ │   ├── index.html.erb
188
+ │   └── show.html.erb
189
+ └── occurrences
190
+ ├── _collection.html.erb
191
+ └── _occurrence.html.erb
192
+ ```
193
+
194
+ You can always take control of the views by creating your own views and/or partials at these paths in your application. For example, if you wanted to overwrite the application layout, you could create a file at `app/views/layouts/solid_errors/application.html.erb`. If you wanted to remove the footer and the automatically disappearing flash messages, as one concrete example, you could define that file as:
195
+
196
+ ```erb
197
+ <!DOCTYPE html>
198
+ <html>
199
+ <head>
200
+ <title>Solid Errors</title>
201
+ <%= csrf_meta_tags %>
202
+ <%= csp_meta_tag %>
203
+
204
+ <%= render "layouts/solid_errors/style" %>
205
+ </head>
206
+ <body class="pb-4">
207
+ <main class="container mx-auto mt-4">
208
+ <%= content_for?(:content) ? yield(:content) : yield %>
209
+ </main>
210
+
211
+ <div class="fixed top-0 left-0 right-0 text-center py-2">
212
+ <% if notice.present? %>
213
+ <p class="py-2 px-3 bg-green-50 text-green-500 font-medium rounded-lg inline-block">
214
+ <%= notice %>
215
+ </p>
216
+ <% end %>
217
+
218
+ <% if alert.present? %>
219
+ <p class="py-2 px-3 bg-red-50 text-red-500 font-medium rounded-lg inline-block">
220
+ <%= alert %>
221
+ </p>
222
+ <% end %>
223
+ </div>
224
+ </body>
225
+ </html>
226
+ ```
227
+
132
228
  ## Development
133
229
 
134
230
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
@@ -3,5 +3,25 @@ module SolidErrors
3
3
  protect_from_forgery with: :exception
4
4
 
5
5
  http_basic_authenticate_with name: SolidErrors.username, password: SolidErrors.password if SolidErrors.password
6
+
7
+ # adapted from: https://github.com/ddnexus/pagy/blob/master/gem/lib/pagy.rb
8
+ OverflowError = Class.new(StandardError)
9
+ class Page
10
+ attr_reader :count, :items, :pages, :first, :last, :prev, :next, :offset, :from, :to
11
+
12
+ def initialize(collection, params)
13
+ @count = collection.count
14
+ @items = (params[:items] || 20).to_i
15
+ @pages = [(@count.to_f / @items).ceil, 1].max
16
+ @page = ((page = (params[:page] || 1).to_i) > @pages) ? @pages : page
17
+ @first = (1 unless @page == 1)
18
+ @last = (@pages unless @page == @pages)
19
+ @prev = (@page - 1 unless @page == 1)
20
+ @next = (@page == @pages) ? nil : @page + 1
21
+ @offset = (@items * (@page - 1))
22
+ @from = [@offset + 1, @count].min
23
+ @to = [@offset + @items, @count].min
24
+ end
25
+ end
6
26
  end
7
27
  end
@@ -1,5 +1,7 @@
1
1
  module SolidErrors
2
2
  class ErrorsController < ApplicationController
3
+ around_action :force_english_locale!
4
+
3
5
  before_action :set_error, only: %i[show update]
4
6
 
5
7
  # GET /errors
@@ -9,13 +11,17 @@ module SolidErrors
9
11
 
10
12
  @errors = Error.unresolved
11
13
  .joins(:occurrences)
12
- .select(errors_table[Arel.star], occurrences_table[:created_at].maximum.as("recent_occurrence"))
14
+ .select(errors_table[Arel.star],
15
+ occurrences_table[:created_at].maximum.as("recent_occurrence"),
16
+ occurrences_table[:id].count.as("occurrences_count"))
13
17
  .group(errors_table[:id])
14
18
  .order(recent_occurrence: :desc)
15
19
  end
16
20
 
17
21
  # GET /errors/1
18
22
  def show
23
+ @page = Page.new(@error.occurrences, params)
24
+ @occurrences = @error.occurrences.offset(@page.offset).limit(@page.items)
19
25
  end
20
26
 
21
27
  # PATCH/PUT /errors/1
@@ -34,5 +40,9 @@ module SolidErrors
34
40
  def set_error
35
41
  @error = Error.find(params[:id])
36
42
  end
43
+
44
+ def force_english_locale!(&action)
45
+ I18n.with_locale(:en, &action)
46
+ end
37
47
  end
38
48
  end
@@ -0,0 +1,15 @@
1
+ module SolidErrors
2
+ # adapted from: https://github.com/codergeek121/email_error_reporter/blob/main/lib/email_error_reporter/error_mailer.rb
3
+ class ErrorMailer < ActionMailer::Base
4
+ def error_occurred(occurrence)
5
+ @occurrence = occurrence
6
+ @error = occurrence.error
7
+
8
+ mail(
9
+ subject: "#{@error.emoji} #{@error.exception_class}",
10
+ from: SolidErrors.email_from,
11
+ to: SolidErrors.email_to
12
+ )
13
+ end
14
+ end
15
+ end
@@ -2,7 +2,7 @@ module SolidErrors
2
2
  # adapted from: https://github.com/honeybadger-io/honeybadger-ruby/blob/master/lib/honeybadger/backtrace.rb
3
3
  class BacktraceLine
4
4
  # Backtrace line regexp (optionally allowing leading X: for windows support).
5
- INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}.freeze
5
+ INPUT_FORMAT = %r{^((?:[a-zA-Z]:)?[^:]+):(\d+)(?::in `([^']+)')?$}
6
6
  STRING_EMPTY = "".freeze
7
7
  GEM_ROOT = "[GEM_ROOT]".freeze
8
8
  PROJECT_ROOT = "[PROJECT_ROOT]".freeze
@@ -2,6 +2,8 @@ module SolidErrors
2
2
  class Occurrence < Record
3
3
  belongs_to :error, class_name: "SolidErrors::Error"
4
4
 
5
+ after_create_commit :send_email, if: -> { SolidErrors.send_emails? && SolidErrors.email_to.present? }
6
+
5
7
  # The parsed exception backtrace. Lines in this backtrace that are from installed gems
6
8
  # have the base path for gem installs replaced by "[GEM_ROOT]", while those in the project
7
9
  # have "[PROJECT_ROOT]".
@@ -17,5 +19,9 @@ module SolidErrors
17
19
  def parse_backtrace(backtrace)
18
20
  Backtrace.parse(backtrace)
19
21
  end
22
+
23
+ def send_email
24
+ ErrorMailer.error_occurred(self).deliver_later
25
+ end
20
26
  end
21
27
  end