exception_hunter 0.1.1 → 0.4.2

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +35 -7
  3. data/app/assets/stylesheets/exception_hunter/base.css +62 -8
  4. data/app/assets/stylesheets/exception_hunter/errors.css +166 -24
  5. data/app/assets/stylesheets/exception_hunter/navigation.css +20 -5
  6. data/app/assets/stylesheets/exception_hunter/sessions.css +71 -0
  7. data/app/controllers/concerns/exception_hunter/authorization.rb +23 -0
  8. data/app/controllers/exception_hunter/application_controller.rb +2 -0
  9. data/app/controllers/exception_hunter/errors_controller.rb +27 -4
  10. data/app/controllers/exception_hunter/resolved_errors_controller.rb +11 -0
  11. data/app/helpers/exception_hunter/errors_helper.rb +7 -0
  12. data/app/helpers/exception_hunter/sessions_helper.rb +16 -0
  13. data/app/models/exception_hunter/application_record.rb +8 -0
  14. data/app/models/exception_hunter/error.rb +21 -8
  15. data/app/models/exception_hunter/error_group.rb +24 -5
  16. data/app/presenters/exception_hunter/dashboard_presenter.rb +54 -0
  17. data/app/presenters/exception_hunter/error_group_presenter.rb +25 -0
  18. data/app/presenters/exception_hunter/error_presenter.rb +10 -1
  19. data/app/views/exception_hunter/devise/sessions/new.html.erb +24 -0
  20. data/app/views/exception_hunter/errors/_error_row.erb +44 -0
  21. data/app/views/exception_hunter/errors/_error_summary.erb +23 -10
  22. data/app/views/exception_hunter/errors/_error_user_data.erb +4 -5
  23. data/app/views/exception_hunter/errors/_errors_table.erb +1 -0
  24. data/app/views/exception_hunter/errors/_last_7_days_errors_table.erb +12 -0
  25. data/app/views/exception_hunter/errors/index.html.erb +71 -30
  26. data/app/views/exception_hunter/errors/pagy/_pagy_nav.html.erb +15 -15
  27. data/app/views/exception_hunter/errors/show.html.erb +58 -22
  28. data/app/views/layouts/exception_hunter/application.html.erb +65 -6
  29. data/app/views/layouts/exception_hunter/exception_hunter_logged_out.html.erb +24 -0
  30. data/config/rails_best_practices.yml +2 -3
  31. data/config/routes.rb +19 -1
  32. data/lib/exception_hunter.rb +12 -2
  33. data/lib/exception_hunter/config.rb +8 -1
  34. data/lib/exception_hunter/devise.rb +17 -0
  35. data/lib/exception_hunter/engine.rb +5 -0
  36. data/{app/services → lib}/exception_hunter/error_creator.rb +17 -5
  37. data/lib/exception_hunter/error_reaper.rb +12 -0
  38. data/lib/exception_hunter/middleware/delayed_job_hunter.rb +69 -0
  39. data/lib/exception_hunter/middleware/request_hunter.rb +71 -0
  40. data/lib/exception_hunter/middleware/sidekiq_hunter.rb +59 -0
  41. data/lib/exception_hunter/tracking.rb +17 -0
  42. data/lib/exception_hunter/user_attributes_collector.rb +4 -0
  43. data/lib/exception_hunter/version.rb +1 -1
  44. data/lib/generators/exception_hunter/create_users/create_users_generator.rb +8 -1
  45. data/lib/generators/exception_hunter/install/install_generator.rb +3 -1
  46. data/lib/generators/exception_hunter/install/templates/create_exception_hunter_error_groups.rb.erb +3 -0
  47. data/lib/generators/exception_hunter/install/templates/exception_hunter.rb.erb +23 -0
  48. data/lib/tasks/exception_hunter_tasks.rake +6 -4
  49. metadata +25 -10
  50. data/config/initializers/exception_hunter.rb +0 -16
  51. data/lib/exception_hunter/railtie.rb +0 -11
  52. data/lib/exception_hunter/request_hunter.rb +0 -41
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 461f614a3acb4efa1cabad37cc849850c45b0f186f627b016c5d48d09684b6c4
4
- data.tar.gz: fa8c5abe1c5a2020d96ce5be459cacc624e227917eca8a5875046f528a021aa4
3
+ metadata.gz: 3cdc954e1b44cc37921b8ba178e55fb404bc6e49e67ae5a946e52e196ca3730e
4
+ data.tar.gz: d852ae798bc6a70543a3bf7a4541d26cdb5c1628e26a3f85decb536093275a1d
5
5
  SHA512:
6
- metadata.gz: a057aff5a6cea927c804120a39b2c708a6e1d363d08d2707461c9fd0f39a8234bdb4cc7ca6b6e153f56cacf18d657eb88e0bd843c08953beef2aacfa2f721108
7
- data.tar.gz: 68eafa484c4350384b5fd8bd38c131462d6634fe9ff344c62ab71c91fcd3995f1b7f8ad4700b5715b7c89ca86741469141364a412887fa5eda680a4f63fd1d30
6
+ metadata.gz: 2d7e25d78109f69be6c37275e69b8300792f645a0a745e679d14c5ac8d2bb682ef60033646d28e6c6e85e937055e45a3e9d6c1fd04d2205092405eb55f9ab9e9
7
+ data.tar.gz: 8d3945a9c830adc7dbe195bb755990948746b46a3d2785b6993f6a6c7777d76d77d01074f134fa38eb2790300c68378dd29bfbf5166ba0a9420d4dc6d290b6ef
data/README.md CHANGED
@@ -1,14 +1,31 @@
1
1
  # ExceptionHunter
2
- Short description and motivation.
3
2
 
4
- ## Usage
5
- How to use my plugin.
3
+ ![CI](https://github.com/rootstrap/exception_hunter/workflows/Rails%20tests/badge.svg)
4
+ [![Maintainability](https://api.codeclimate.com/v1/badges/86f6aaa2377c894f8ee4/maintainability)](https://codeclimate.com/github/rootstrap/exception_hunter/maintainability)
5
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/86f6aaa2377c894f8ee4/test_coverage)](https://codeclimate.com/github/rootstrap/exception_hunter/test_coverage)
6
+
7
+ ![Index screenshot](doc/screenshot.png)
8
+
9
+ Exception Hunter is a Rails engine meant to track errors in your Rails project. It works
10
+ by using your Postgres database to save errors with their corresponding metadata (like backtrace
11
+ or environment data at the time of failure).
12
+
13
+ To do so we hook to various points of your application where we can rescue from errors, track and
14
+ then re-raise those errors so they are handled normally. As such, the gem does not conflict with any
15
+ other service so you can have your favorite error tracking service running in parallel with Exception Hunter
16
+ while you decide which you like best.
17
+
18
+ ## Motivation
19
+
20
+ Error tracking is one of the most important tools a developer can have in their toolset. As such
21
+ we think it'd be nice to provide a way for everyone to have it in their project, be it a personal
22
+ project, and MVP or something else.
6
23
 
7
24
  ## Installation
8
25
  Add Exception Hunter to your application's Gemfile:
9
26
 
10
27
  ```ruby
11
- gem 'exception_hunter', '~> 0.1.1'
28
+ gem 'exception_hunter', '~> 0.4.2'
12
29
  ```
13
30
 
14
31
  You may also need to add [Devise](https://github.com/heartcombo/devise) to your Gemfile
@@ -26,13 +43,24 @@ $ rails generate exception_hunter:install
26
43
 
27
44
  This will create an initializer and invoke Devise to
28
45
  create an `AdminUser` which will be used for authentication to access the dashboard. If you already
29
- have this user created (Devise uses the same model) you can run the command with the `--skip-users` flag.
46
+ have this user created ([ActiveAdmin](https://github.com/activeadmin/activeadmin) uses the same model)
47
+ you can run the command with the `--skip-users` flag.
30
48
 
31
49
  Additionally it should add the 'ExceptionHunter.routes(self)' line to your routes, which means you can go to
32
50
  `/exception_hunter/errors` in your browser and start enjoying some good old fashioned exception tracking!
33
51
 
34
- ## Contributing
35
- Contribution directions go here.
52
+ ## Stale data
53
+
54
+ You can get rid of stale errors by running the rake task to purge them:
55
+
56
+ ```bash
57
+ $ rake exception_hunter:purge_errors
58
+ ```
59
+
60
+ We recommend you run this task once in a while to de-clutter your DB, using a recurring tasks once
61
+ a week would be ideal. You can also purge errors by running `ExceptionHunter::ErrorReaper.purge`.
62
+
63
+ The time it takes for an error to go stale defaults to 45 days but it's configurable via the initializer.
36
64
 
37
65
  ## License
38
66
  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
- --main-color: #C8193C;
3
- --secondary-color: #F4F5F6;
4
- --link-color: #158FEF;
5
- --border-color: #D1D1D1;
6
- --file-name-color: #16AF90
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: 5.5rem auto auto;
35
+ margin: 6.5rem auto auto;
36
+ }
37
+
38
+ .text--underline {
39
+ text-decoration: underline;
11
40
  }
12
41
 
13
42
  a {
14
- color: var(--link-color);
43
+ color: inherit;
15
44
  }
16
45
 
17
46
  a:hover, a:focus, a:active {
18
- color: var(--main-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,61 +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
+ }
5
25
 
6
- .row.statistics-row {
7
- padding-top: 1rem;
26
+ li.errors-tab {
27
+ margin-bottom: 0;
8
28
  }
9
29
 
10
- .statistics__cell {
11
- color: var(--main-color);
12
- background-color: var(--secondary-color);
13
- border: 1px solid var(--border-color);
14
- height: 5rem;
15
- border-radius: 10px;
30
+ .errors-tab--active, li.errors-tab a[aria-selected="true"] .errors-tab__content {
31
+ background-color: #FFF;
32
+ color: var(--highlight-color);
33
+ }
34
+
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
- font-size: 2.2rem;
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-top: 1rem;
24
- padding-bottom: 1rem;
25
- border-bottom: 1px solid;
85
+ padding: 1rem;
86
+ }
87
+
88
+ .error-row:not(.error-row--header) {
89
+ border: 1px solid var(--border-grey);
26
90
  }
27
91
 
28
- .row.error-row-no-border {
29
- padding-top: 1rem;
30
- padding-bottom: 1rem;
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
- font-weight: bold;
97
+ background-color: var(--header-grey);
98
+ font-weight: 500;
99
+ color: #000;
100
+ }
101
+
102
+ .error-cell__message {
103
+ overflow-x: hidden;
35
104
  }
36
105
 
37
- .error-cell.error-cell--highlight {
38
- color: var(--main-color);
106
+ .error-cell__tags {
107
+ font-weight: 500;
108
+ font-size: 12px;
109
+ color: #000;
110
+ padding-bottom: 3px;
111
+ }
112
+
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
- font-size: 20px;
43
- border-bottom: 1px solid var(--border-color);
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(--main-color);
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(--main-color);
197
+ color: var(--highlight-color);
198
+ }
199
+
200
+ .tracked-data {
201
+ border-left-color: var(--highlight-color);
60
202
  }
61
203
 
62
204
  .backtrace {
@@ -76,7 +218,7 @@
76
218
 
77
219
  .backtrace-line__line-number {
78
220
  margin-right: 5px;
79
- color: var(--main-color);
221
+ color: var(--highlight-color);
80
222
  }
81
223
 
82
224
  .backtrace-line__file-name {
@@ -1,8 +1,7 @@
1
1
  .nav {
2
- background: var(--secondary-color);
3
- border-bottom: .1rem solid var(--border-color);
2
+ background: #000;
4
3
  display: block;
5
- height: 5.2rem;
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
- .nav__logo img {
20
- height: 100%;
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
+ }