exception_hunter 0.2.0 → 0.3.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 +29 -6
- data/app/assets/stylesheets/exception_hunter/base.css +62 -8
- data/app/assets/stylesheets/exception_hunter/errors.css +163 -25
- data/app/assets/stylesheets/exception_hunter/navigation.css +20 -5
- data/app/assets/stylesheets/exception_hunter/sessions.css +71 -0
- data/app/controllers/concerns/exception_hunter/authorization.rb +23 -0
- data/app/controllers/exception_hunter/application_controller.rb +2 -0
- data/app/controllers/exception_hunter/errors_controller.rb +27 -4
- data/app/controllers/exception_hunter/resolved_errors_controller.rb +11 -0
- data/app/helpers/exception_hunter/sessions_helper.rb +16 -0
- data/app/models/exception_hunter/application_record.rb +8 -0
- data/app/models/exception_hunter/error.rb +20 -7
- data/app/models/exception_hunter/error_group.rb +23 -4
- data/app/presenters/exception_hunter/dashboard_presenter.rb +54 -0
- data/app/presenters/exception_hunter/error_group_presenter.rb +25 -0
- data/app/presenters/exception_hunter/error_presenter.rb +1 -0
- data/app/views/exception_hunter/devise/sessions/new.html.erb +24 -0
- data/app/views/exception_hunter/errors/_error_row.erb +44 -0
- data/app/views/exception_hunter/errors/_error_summary.erb +5 -5
- data/app/views/exception_hunter/errors/_errors_table.erb +1 -0
- data/app/views/exception_hunter/errors/_last_7_days_errors_table.erb +12 -0
- data/app/views/exception_hunter/errors/index.html.erb +71 -30
- data/app/views/exception_hunter/errors/pagy/_pagy_nav.html.erb +15 -15
- data/app/views/exception_hunter/errors/show.html.erb +58 -22
- data/app/views/layouts/exception_hunter/application.html.erb +65 -6
- data/app/views/layouts/exception_hunter/exception_hunter_logged_out.html.erb +24 -0
- data/config/rails_best_practices.yml +2 -2
- data/config/routes.rb +19 -1
- data/lib/exception_hunter.rb +11 -1
- data/lib/exception_hunter/config.rb +8 -1
- data/lib/exception_hunter/devise.rb +17 -0
- data/{app/services → lib}/exception_hunter/error_creator.rb +15 -3
- data/lib/exception_hunter/error_reaper.rb +12 -0
- data/lib/exception_hunter/middleware/request_hunter.rb +1 -0
- data/lib/exception_hunter/middleware/sidekiq_hunter.rb +1 -0
- data/lib/exception_hunter/tracking.rb +16 -0
- data/lib/exception_hunter/user_attributes_collector.rb +4 -0
- data/lib/exception_hunter/version.rb +1 -1
- data/lib/generators/exception_hunter/create_users/create_users_generator.rb +8 -1
- data/lib/generators/exception_hunter/install/install_generator.rb +3 -1
- data/lib/generators/exception_hunter/install/templates/create_exception_hunter_error_groups.rb.erb +3 -0
- data/lib/generators/exception_hunter/install/templates/exception_hunter.rb.erb +23 -0
- data/lib/tasks/exception_hunter_tasks.rake +6 -4
- metadata +18 -5
- data/config/initializers/exception_hunter.rb +0 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ba4ba0c2e1205126ac00e8d0c27b9b98cc3b932dff902e6d7552b7bb640e681
|
4
|
+
data.tar.gz: 49b05057f76bb754bec371065918aeb0cb087208794326c78b837fb894af2fad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dfd7faf102765439718b72f1c643593d48c6f1613db7ea573a4cb0ea66206819d6fcf5f17eb9f229beb31efa20f76901e995539703ed266073986cdae5795712
|
7
|
+
data.tar.gz: b9711187a6887b4542973bc5f1c687a9e6034dc5b136cc6755fec9126d4ccce4311bbad8eafdfd49c53be7e437c63f69f505b4868f46da3abf387e3e6bc02ab1
|
data/README.md
CHANGED
@@ -1,14 +1,27 @@
|
|
1
1
|
# ExceptionHunter
|
2
|
-
Short description and motivation.
|
3
2
|
|
4
|
-
|
5
|
-
|
3
|
+

|
4
|
+
|
5
|
+
Exception Hunter is a Rails engine meant to track errors in your Rails project. It works
|
6
|
+
by using your Postgres database to save errors with their corresponding metadata (like backtrace
|
7
|
+
or environment data at the time of failure).
|
8
|
+
|
9
|
+
To do so we hook to various points of your application where we can rescue from errors, track and
|
10
|
+
then re-raise those errors so they are handled normally. As such, the gem does not conflict with any
|
11
|
+
other service so you can have your favorite error tracking service running in parallel with Exception Hunter
|
12
|
+
while you decide which you like best.
|
13
|
+
|
14
|
+
## Motivation
|
15
|
+
|
16
|
+
Error tracking is one of the most important tools a developer can have in their toolset. As such
|
17
|
+
we think it'd be nice to provide a way for everyone to have it in their project, be it a personal
|
18
|
+
project, and MVP or something else.
|
6
19
|
|
7
20
|
## Installation
|
8
21
|
Add Exception Hunter to your application's Gemfile:
|
9
22
|
|
10
23
|
```ruby
|
11
|
-
gem 'exception_hunter', '~> 0.
|
24
|
+
gem 'exception_hunter', '~> 0.3.0'
|
12
25
|
```
|
13
26
|
|
14
27
|
You may also need to add [Devise](https://github.com/heartcombo/devise) to your Gemfile
|
@@ -32,8 +45,18 @@ you can run the command with the `--skip-users` flag.
|
|
32
45
|
Additionally it should add the 'ExceptionHunter.routes(self)' line to your routes, which means you can go to
|
33
46
|
`/exception_hunter/errors` in your browser and start enjoying some good old fashioned exception tracking!
|
34
47
|
|
35
|
-
##
|
36
|
-
|
48
|
+
## Stale data
|
49
|
+
|
50
|
+
You can get rid of stale errors by running the rake task to purge them:
|
51
|
+
|
52
|
+
```bash
|
53
|
+
$ rake exception_hunter:purge_errors
|
54
|
+
```
|
55
|
+
|
56
|
+
We recommend you run this task once in a while to de-clutter your DB, using a recurring tasks once
|
57
|
+
a week would be ideal. You can also purge errors by running `ExceptionHunter::ErrorReaper.purge`.
|
58
|
+
|
59
|
+
The time it takes for an error to go stale defaults to 45 days but it's configurable via the initializer.
|
37
60
|
|
38
61
|
## License
|
39
62
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -1,19 +1,73 @@
|
|
1
1
|
:root {
|
2
|
-
--
|
3
|
-
--
|
4
|
-
--
|
5
|
-
--
|
6
|
-
--
|
2
|
+
--background-grey: #E5E5E5;
|
3
|
+
--highlight-color: #CF4031;
|
4
|
+
--highlight-good-color: #2CBB85;
|
5
|
+
--highlight-inactive-color: #808183;
|
6
|
+
--inactive-grey: #D1D1D3;
|
7
|
+
--focused-grey: #808183;
|
8
|
+
--highlighted-link-blue: #0036F7;
|
9
|
+
--header-grey: #F8F8F8;
|
10
|
+
--border-grey: #F1F2F5;
|
11
|
+
--file-name-color: #2CBB85;
|
12
|
+
--tag-color: #EAE639;
|
13
|
+
}
|
14
|
+
|
15
|
+
body {
|
16
|
+
font-family: 'Inter', sans-serif;
|
17
|
+
background-color: var(--background-grey);
|
18
|
+
}
|
19
|
+
|
20
|
+
.container {
|
21
|
+
padding: 0;
|
22
|
+
}
|
23
|
+
|
24
|
+
.row {
|
25
|
+
margin: 0;
|
26
|
+
width: 100%;
|
27
|
+
}
|
28
|
+
|
29
|
+
.row .column {
|
30
|
+
padding: 0;
|
31
|
+
margin-bottom: 0;
|
7
32
|
}
|
8
33
|
|
9
34
|
.wrapper {
|
10
|
-
margin:
|
35
|
+
margin: 6.5rem auto auto;
|
36
|
+
}
|
37
|
+
|
38
|
+
.text--underline {
|
39
|
+
text-decoration: underline;
|
11
40
|
}
|
12
41
|
|
13
42
|
a {
|
14
|
-
color:
|
43
|
+
color: inherit;
|
15
44
|
}
|
16
45
|
|
17
46
|
a:hover, a:focus, a:active {
|
18
|
-
color:
|
47
|
+
color: inherit;
|
48
|
+
}
|
49
|
+
|
50
|
+
form {
|
51
|
+
margin-bottom: 0;
|
52
|
+
}
|
53
|
+
|
54
|
+
.flash.flash--notice {
|
55
|
+
background-color: #FFF;
|
56
|
+
margin-bottom: 2rem;
|
57
|
+
padding: 0.7rem 2rem;
|
58
|
+
border-radius: 5px;
|
59
|
+
line-height: 3.8rem;
|
60
|
+
font-weight: 400;
|
61
|
+
}
|
62
|
+
|
63
|
+
.button.button-dismiss {
|
64
|
+
margin-bottom: 0;
|
65
|
+
padding: 0;
|
66
|
+
color: var(--focused-grey);
|
67
|
+
width: 100%;
|
68
|
+
text-align: right;
|
69
|
+
}
|
70
|
+
|
71
|
+
.button.button-dismiss:hover, .button.button-dismiss:focus, .button.button-dismiss:active {
|
72
|
+
color: var(--inactive-grey);
|
19
73
|
}
|
@@ -2,65 +2,203 @@
|
|
2
2
|
Place all the styles related to the matching controller here.
|
3
3
|
They will automatically be included in application.css.
|
4
4
|
*/
|
5
|
+
.errors__container {
|
6
|
+
background-color: #FFF;
|
7
|
+
padding: 32px;
|
8
|
+
border-radius: 0 5px 5px 5px;
|
9
|
+
}
|
10
|
+
|
11
|
+
.errors-tabs {
|
12
|
+
display: flex;
|
13
|
+
}
|
14
|
+
|
15
|
+
ul.errors-tabs {
|
16
|
+
list-style-type: none;
|
17
|
+
margin-bottom: 0;
|
18
|
+
}
|
19
|
+
|
20
|
+
.errors-tab {
|
21
|
+
border-radius: 5px 5px 0 0;
|
22
|
+
margin-right: 1rem;
|
23
|
+
background-color: var(--inactive-grey);
|
24
|
+
}
|
25
|
+
|
26
|
+
li.errors-tab {
|
27
|
+
margin-bottom: 0;
|
28
|
+
}
|
5
29
|
|
6
|
-
.
|
7
|
-
|
30
|
+
.errors-tab--active, li.errors-tab a[aria-selected="true"] .errors-tab__content {
|
31
|
+
background-color: #FFF;
|
32
|
+
color: var(--highlight-color);
|
8
33
|
}
|
9
34
|
|
10
|
-
.
|
11
|
-
color: var(--
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
35
|
+
.errors-tab__resolved.errors-tab--active {
|
36
|
+
color: var(--highlight-good-color);
|
37
|
+
}
|
38
|
+
|
39
|
+
.errors-tab__content {
|
40
|
+
padding: 1rem;
|
41
|
+
display: flex;
|
42
|
+
}
|
43
|
+
|
44
|
+
.errors-tab__badge {
|
45
|
+
background: var(--highlight-inactive-color);
|
46
|
+
border-radius: 5px;
|
47
|
+
color: #FFF;
|
48
|
+
padding: 4px 8px;
|
49
|
+
}
|
50
|
+
|
51
|
+
.errors-tab--active .errors-tab__badge {
|
52
|
+
background-color: var(--highlight-color);
|
53
|
+
}
|
54
|
+
|
55
|
+
.errors-tab__resolved.errors-tab--active .errors-tab__badge {
|
56
|
+
background-color: var(--highlight-good-color);
|
57
|
+
}
|
58
|
+
|
59
|
+
.errors-tab__description {
|
60
|
+
margin-left: 1.3rem;
|
16
61
|
display: flex;
|
17
|
-
align-items: center;
|
18
62
|
justify-content: center;
|
19
|
-
|
63
|
+
align-items: center;
|
64
|
+
}
|
65
|
+
|
66
|
+
.button.purge-button {
|
67
|
+
background-color: var(--highlight-color);
|
68
|
+
border: none;
|
69
|
+
}
|
70
|
+
|
71
|
+
.button.purge-button:hover, .button.purge-button:focus {
|
72
|
+
background: var(--focused-grey);
|
73
|
+
}
|
74
|
+
|
75
|
+
.errors-date-group {
|
76
|
+
background-color: var(--header-grey);
|
77
|
+
padding: 0.5rem 1rem;
|
78
|
+
}
|
79
|
+
|
80
|
+
.errors-date-group ~ .errors-date-group {
|
81
|
+
border-bottom: 1px solid var(--border-grey);
|
20
82
|
}
|
21
83
|
|
22
84
|
.row.error-row {
|
23
|
-
padding
|
24
|
-
padding-bottom: 1rem;
|
25
|
-
border-bottom: 1px solid;
|
85
|
+
padding: 1rem;
|
26
86
|
}
|
27
87
|
|
28
|
-
.row.error-row
|
29
|
-
|
30
|
-
|
88
|
+
.error-row:not(.error-row--header) {
|
89
|
+
border: 1px solid var(--border-grey);
|
90
|
+
}
|
91
|
+
|
92
|
+
.error-message, .error-message:hover, .error-message:focus, .error-message:active {
|
93
|
+
color: var(--highlighted-link-blue);
|
31
94
|
}
|
32
95
|
|
33
96
|
.error-row.error-row--header {
|
34
|
-
|
97
|
+
background-color: var(--header-grey);
|
98
|
+
font-weight: 500;
|
99
|
+
color: #000;
|
100
|
+
}
|
101
|
+
|
102
|
+
.error-cell__message {
|
103
|
+
overflow-x: hidden;
|
104
|
+
}
|
105
|
+
|
106
|
+
.error-cell__tags {
|
107
|
+
font-weight: 500;
|
108
|
+
font-size: 12px;
|
109
|
+
color: #000;
|
110
|
+
padding-bottom: 3px;
|
35
111
|
}
|
36
112
|
|
37
|
-
.error-
|
38
|
-
|
113
|
+
.error-cell__tags .error-tag {
|
114
|
+
background-color: var(--tag-color);
|
115
|
+
border-radius: 5px;
|
116
|
+
padding: 1px 5px 1px 5px;
|
39
117
|
}
|
40
118
|
|
41
119
|
.error-title {
|
42
|
-
|
43
|
-
|
120
|
+
color: var(--highlighted-link-blue);
|
121
|
+
padding-left: 2rem;
|
122
|
+
}
|
123
|
+
|
124
|
+
.error-occurrence__header {
|
125
|
+
background: #FFF;
|
126
|
+
padding: 2rem 1rem;
|
127
|
+
margin-bottom: 2rem;
|
128
|
+
border-radius: 5px;
|
129
|
+
}
|
130
|
+
|
131
|
+
.button_to .button.button-outlined.resolve-button {
|
132
|
+
color: var(--highlight-good-color);
|
133
|
+
border-color: var(--highlight-good-color);
|
134
|
+
font-size: 10px;
|
135
|
+
padding: 0 1rem;
|
136
|
+
height: 3rem;
|
137
|
+
line-height: 3rem;
|
138
|
+
}
|
139
|
+
|
140
|
+
.button_to .button.resolve-button {
|
141
|
+
color: #FFF;
|
142
|
+
background-color: var(--highlight-good-color);
|
143
|
+
border-color: var(--highlight-good-color);
|
144
|
+
font-size: 10px;
|
145
|
+
padding: 0 1rem;
|
146
|
+
height: 3rem;
|
147
|
+
line-height: 3rem;
|
148
|
+
margin-bottom: 0;
|
149
|
+
}
|
150
|
+
|
151
|
+
.button.resolve-button:hover, .button.resolve-button:focus {
|
152
|
+
color: var(--focused-grey);
|
153
|
+
border-color: var(--focused-grey);
|
44
154
|
}
|
45
155
|
|
46
156
|
.error-occurred_at {
|
47
|
-
color: var(--
|
157
|
+
color: var(--highlight-color);
|
48
158
|
font-size: 14px;
|
49
159
|
margin-top: 0.5em;
|
50
160
|
margin-bottom: 2em;
|
51
161
|
}
|
52
162
|
|
163
|
+
.error-occurrences__nav {
|
164
|
+
display: flex;
|
165
|
+
justify-content: flex-end;
|
166
|
+
height: 100%;
|
167
|
+
align-items: center;
|
168
|
+
}
|
169
|
+
|
170
|
+
.button.button-outline.error-occurrences__nav-link {
|
171
|
+
margin-bottom: 0;
|
172
|
+
padding: 0 1rem;
|
173
|
+
height: 2.5rem;
|
174
|
+
line-height: 2.5rem;
|
175
|
+
margin-right: 0.5rem;
|
176
|
+
border-color: #000;
|
177
|
+
color: #000;
|
178
|
+
}
|
179
|
+
|
180
|
+
.button.button-outline.error-occurrences__nav-link[disabled="disabled"],
|
181
|
+
.button.button-outline.error-occurrences__nav-link[disabled="disabled"]:focus,
|
182
|
+
.button.button-outline.error-occurrences__nav-link[disabled="disabled"]:hover {
|
183
|
+
border-color: var(--highlight-inactive-color);
|
184
|
+
color: var(--highlight-inactive-color);
|
185
|
+
}
|
186
|
+
|
187
|
+
.error-occurrences__nav-current {
|
188
|
+
margin: 0 2rem;
|
189
|
+
}
|
190
|
+
|
53
191
|
.tab-content {
|
54
192
|
padding: 1em 0.5em;
|
55
193
|
}
|
56
194
|
|
57
195
|
.data-title {
|
58
196
|
font-weight: bold;
|
59
|
-
color: var(--
|
197
|
+
color: var(--highlight-color);
|
60
198
|
}
|
61
199
|
|
62
200
|
.tracked-data {
|
63
|
-
border-left-color: var(--
|
201
|
+
border-left-color: var(--highlight-color);
|
64
202
|
}
|
65
203
|
|
66
204
|
.backtrace {
|
@@ -80,7 +218,7 @@
|
|
80
218
|
|
81
219
|
.backtrace-line__line-number {
|
82
220
|
margin-right: 5px;
|
83
|
-
color: var(--
|
221
|
+
color: var(--highlight-color);
|
84
222
|
}
|
85
223
|
|
86
224
|
.backtrace-line__file-name {
|
@@ -1,8 +1,7 @@
|
|
1
1
|
.nav {
|
2
|
-
background:
|
3
|
-
border-bottom: .1rem solid var(--border-color);
|
2
|
+
background: #000;
|
4
3
|
display: block;
|
5
|
-
height:
|
4
|
+
height: 4.2rem;
|
6
5
|
left: 0;
|
7
6
|
max-width: 100%;
|
8
7
|
position: fixed;
|
@@ -16,6 +15,22 @@
|
|
16
15
|
height: 100%;
|
17
16
|
}
|
18
17
|
|
19
|
-
.
|
20
|
-
height:
|
18
|
+
.nav__title {
|
19
|
+
line-height: 4.2rem;
|
20
|
+
font-style: normal;
|
21
|
+
font-weight: 600;
|
22
|
+
font-size: 16px;
|
23
|
+
color: #FFF;
|
24
|
+
}
|
25
|
+
|
26
|
+
.footer {
|
27
|
+
text-align: center;
|
28
|
+
padding-top: 4rem;
|
29
|
+
padding-bottom: 1rem;
|
30
|
+
}
|
31
|
+
|
32
|
+
.logout {
|
33
|
+
line-height: 4.2rem;
|
34
|
+
color: #FFF;
|
35
|
+
text-align: right;
|
21
36
|
}
|
@@ -0,0 +1,71 @@
|
|
1
|
+
.login_form_container {
|
2
|
+
margin: 0rem auto auto;
|
3
|
+
display: flex;
|
4
|
+
max-width: 75%;
|
5
|
+
margin-top: 20rem;
|
6
|
+
width: 910px;
|
7
|
+
height: 356px;
|
8
|
+
font-family: 'Inter', sans-serif;
|
9
|
+
background-color: white;
|
10
|
+
}
|
11
|
+
|
12
|
+
.login_left_container {
|
13
|
+
width: 455px;
|
14
|
+
text-align: center;
|
15
|
+
width: 38rem;
|
16
|
+
background-color: black;
|
17
|
+
|
18
|
+
}
|
19
|
+
|
20
|
+
.left_column {
|
21
|
+
max-width: 50%;
|
22
|
+
padding-top: 15%;
|
23
|
+
padding-left: 10%;
|
24
|
+
line-height: 130%;
|
25
|
+
color: white;
|
26
|
+
text-align: left;
|
27
|
+
font-size: 30px;
|
28
|
+
font-weight: 600;
|
29
|
+
}
|
30
|
+
|
31
|
+
.login_right_container {
|
32
|
+
width: 350px;
|
33
|
+
margin: 3rem 3.5rem 1rem;
|
34
|
+
font-size: 24px;
|
35
|
+
font-weight: 400;
|
36
|
+
text-align: left;
|
37
|
+
line-height: 29px;
|
38
|
+
line-height: 100%;
|
39
|
+
color: black;
|
40
|
+
}
|
41
|
+
|
42
|
+
.login_row {
|
43
|
+
margin: 2rem 0rem 0rem;
|
44
|
+
width: 100%;
|
45
|
+
align-items: center;
|
46
|
+
}
|
47
|
+
|
48
|
+
.login_button{
|
49
|
+
margin: 3rem 3rem 0rem;
|
50
|
+
align-items: right;
|
51
|
+
}
|
52
|
+
|
53
|
+
.button-log-in {
|
54
|
+
background-color: #2CBB85!important;
|
55
|
+
border-color: #2CBB85!important;
|
56
|
+
}
|
57
|
+
|
58
|
+
.field{
|
59
|
+
border: 0.1rem solid black;
|
60
|
+
border-radius: .4rem;
|
61
|
+
}
|
62
|
+
|
63
|
+
input[type='password'],
|
64
|
+
input[type='email'],
|
65
|
+
textarea:focus,
|
66
|
+
select:focus {
|
67
|
+
border-color: black!important;
|
68
|
+
outline: 0;
|
69
|
+
font-size: 1.2rem!important;
|
70
|
+
color: black!important;
|
71
|
+
}
|