solid_errors 0.3.5 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +98 -2
- data/app/controllers/solid_errors/application_controller.rb +20 -0
- data/app/controllers/solid_errors/errors_controller.rb +11 -1
- data/app/mailers/solid_errors/error_mailer.rb +15 -0
- data/app/models/solid_errors/backtrace_line.rb +1 -1
- data/app/models/solid_errors/occurrence.rb +6 -0
- data/app/views/layouts/solid_errors/_style.html +1114 -0
- data/app/views/layouts/solid_errors/application.html.erb +4 -1085
- data/app/views/solid_errors/error_mailer/error_occurred.html.erb +17 -0
- data/app/views/solid_errors/errors/_error.html.erb +98 -27
- data/app/views/solid_errors/errors/_row.html.erb +31 -0
- data/app/views/solid_errors/errors/index.html.erb +1 -1
- data/app/views/solid_errors/errors/show.html.erb +5 -101
- data/app/views/solid_errors/occurrences/_collection.html.erb +38 -3
- data/app/views/solid_errors/occurrences/_occurrence.html.erb +2 -1
- data/lib/generators/solid_errors/install/templates/create_solid_errors_tables.rb.erb +5 -6
- data/lib/solid_errors/engine.rb +1 -1
- data/lib/solid_errors/subscriber.rb +3 -2
- data/lib/solid_errors/version.rb +1 -1
- data/lib/solid_errors.rb +15 -0
- metadata +77 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b0f7fa69e2efa8949c085b3ba7b72b407dd3d670643c76260a6f8addf836305f
|
4
|
+
data.tar.gz: f931d1de445d5d3fe124dc352e2a81513d174d37ed6ae923122e95e2468ccc7e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3a2eb10327f7a11569d1cc90f2418bd28252d177b23c329c8a4105b2cb22a4fa17e36b44dbe5f1f341c222de2be9ba149fb4ce6e308b5c6aa99b1160de678b83
|
7
|
+
data.tar.gz: 52f3d7fd1669173da1ce9155370d92bae1678c4ae4326c2637e026c93cc9eeb84e091c587f8322fd6b9f9228c79f31262c0cd9b42be98d65837004754efc2ec3
|
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,
|
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
|
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],
|
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 `([^']+)')?$}
|
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
|