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 +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
@@ -0,0 +1,17 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<title>Solid Errors | <%= @error.emoji %> <%= @error.exception_class %></title>
|
4
|
+
<%= render "layouts/solid_errors/style" %>
|
5
|
+
</head>
|
6
|
+
<body>
|
7
|
+
<%= render "solid_errors/errors/error",
|
8
|
+
error: @error,
|
9
|
+
show_actions: false %>
|
10
|
+
|
11
|
+
<br>
|
12
|
+
<br>
|
13
|
+
|
14
|
+
<%= render "solid_errors/occurrences/occurrence",
|
15
|
+
occurrence: @occurrence %>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -1,31 +1,102 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
1
|
+
<%# locals: (error:, show_actions: true) -%>
|
2
|
+
|
3
|
+
<%= tag.section id: dom_id(error), class: "space-y-6" do %>
|
4
|
+
<div class="flex justify-between items-center">
|
5
|
+
<%= tag.h1 class: "font-bold flex items-center text-2xl gap-2" do %>
|
4
6
|
<%= error.emoji %>
|
5
|
-
|
6
|
-
<strong><code><%= error.exception_class %></code></strong>
|
7
|
-
<% end %>
|
7
|
+
<code><%= error.exception_class %></code>
|
8
8
|
from
|
9
9
|
<em><code><%= error.source %></code></em>
|
10
|
-
</div>
|
11
|
-
<pre class="whitespace-pre-wrap ml-6 mt-4"><%= error.message %></pre>
|
12
|
-
</td>
|
13
|
-
<td scope="col" class="whitespace-nowrap px-3 py-4 pt-7 text-gray-500 text-right">
|
14
|
-
<%= error.occurrences.size %>
|
15
|
-
</td>
|
16
|
-
<td scope="col" class="whitespace-nowrap px-3 py-4 pt-7 text-gray-500 text-right">
|
17
|
-
<% last_seen_at = error.occurrences.maximum(:created_at) %>
|
18
|
-
<abbr title="<%= last_seen_at.iso8601 %>" class="cursor-help">
|
19
|
-
<%= time_tag last_seen_at, time_ago_in_words(last_seen_at, scope: 'datetime.distance_in_words.short') %>
|
20
|
-
</abbr>
|
21
|
-
</td>
|
22
|
-
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-3">
|
23
|
-
<%= button_to error_path(error), method: :patch, class: "inline-flex items-center justify-center gap-2 font-medium cursor-pointer border rounded-lg py-3 px-5 bg-transparent text-blue-500 border-blue-500 hover:ring-blue-200 hover:ring-8", params: { error: { resolved_at: Time.now } } do %>
|
24
|
-
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
|
25
|
-
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0"/>
|
26
|
-
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0z"/>
|
27
|
-
</svg>
|
28
|
-
<span>Resolve<span class="sr-only">, Error #<%= error.id %></span></span>
|
29
10
|
<% end %>
|
30
|
-
|
31
|
-
|
11
|
+
|
12
|
+
<small class="text-base">
|
13
|
+
#<code><%= error.id %></code>
|
14
|
+
</small>
|
15
|
+
</div>
|
16
|
+
|
17
|
+
<pre class=""><%= error.message %></pre>
|
18
|
+
|
19
|
+
<dl class="flex-1 grid grid-cols-2 gap-x-4">
|
20
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
21
|
+
<dt class="font-bold">
|
22
|
+
<%= SolidErrors::Error.human_attribute_name(:first_seen) %>
|
23
|
+
</dt>
|
24
|
+
<dd class="inline-flex items-center gap-1">
|
25
|
+
<% first_seen_at = error.occurrences.minimum(:created_at) %>
|
26
|
+
|
27
|
+
<abbr title="<%= first_seen_at.iso8601 %>" class="cursor-help">
|
28
|
+
<%= time_tag first_seen_at, "#{time_ago_in_words(first_seen_at)} ago" %>
|
29
|
+
</abbr>
|
30
|
+
</dd>
|
31
|
+
</div>
|
32
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
33
|
+
<dt class="font-bold">
|
34
|
+
<%= SolidErrors::Error.human_attribute_name(:last_seen) %>
|
35
|
+
</dt>
|
36
|
+
<dd class="inline-flex items-center gap-1">
|
37
|
+
<% last_seen_at = error.occurrences.maximum(:created_at) %>
|
38
|
+
|
39
|
+
<abbr title="<%= last_seen_at.iso8601 %>" class="cursor-help">
|
40
|
+
<%= time_tag last_seen_at, "#{time_ago_in_words(last_seen_at)} ago" %>
|
41
|
+
</abbr>
|
42
|
+
</dd>
|
43
|
+
</div>
|
44
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
45
|
+
<dt class="font-bold">
|
46
|
+
<%= SolidErrors::Error.human_attribute_name(:occurrences) %>
|
47
|
+
</dt>
|
48
|
+
<dd class="inline-flex items-center gap-1">
|
49
|
+
<%= error.occurrences.size %>
|
50
|
+
</dd>
|
51
|
+
</div>
|
52
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
53
|
+
<dt class="font-bold">
|
54
|
+
<%= SolidErrors::Error.human_attribute_name(:exception_class) %>
|
55
|
+
</dt>
|
56
|
+
<dd class="inline-flex items-center gap-1">
|
57
|
+
<code><%= error.exception_class %></code>
|
58
|
+
</dd>
|
59
|
+
</div>
|
60
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
61
|
+
<dt class="font-bold">
|
62
|
+
<%= SolidErrors::Error.human_attribute_name(:severity) %>
|
63
|
+
</dt>
|
64
|
+
<dd class="inline-flex items-center gap-1">
|
65
|
+
<%= error.emoji %>
|
66
|
+
<span class="<%= error.badge_classes %>">
|
67
|
+
<%= error.severity %>
|
68
|
+
</span>
|
69
|
+
</dd>
|
70
|
+
</div>
|
71
|
+
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
72
|
+
<dt class="font-bold">
|
73
|
+
<%= SolidErrors::Error.human_attribute_name(:source) %>
|
74
|
+
</dt>
|
75
|
+
<dd class="inline-flex items-center gap-1">
|
76
|
+
<em><%= error.source %></em>
|
77
|
+
</dd>
|
78
|
+
</div>
|
79
|
+
<div class="flex items-start justify-between flex-wrap gap-x-2">
|
80
|
+
<dt class="font-bold">
|
81
|
+
<%= SolidErrors::Error.human_attribute_name(:project_root) %>
|
82
|
+
</dt>
|
83
|
+
<dd class="">
|
84
|
+
<span><%= SolidErrors::BacktraceLine::RAILS_ROOT %></span>
|
85
|
+
</dd>
|
86
|
+
</div>
|
87
|
+
<div class="flex items-start justify-between flex-wrap gap-x-2">
|
88
|
+
<dt class="font-bold">
|
89
|
+
<%= SolidErrors::Error.human_attribute_name(:gem_root) %>
|
90
|
+
</dt>
|
91
|
+
<dd class="">
|
92
|
+
<ul>
|
93
|
+
<% Gem.path.each do |path| %>
|
94
|
+
<li><%= path %></li>
|
95
|
+
<% end %>
|
96
|
+
</ul>
|
97
|
+
</dd>
|
98
|
+
</div>
|
99
|
+
</dl>
|
100
|
+
|
101
|
+
<%= render "solid_errors/errors/actions", error: error if show_actions %>
|
102
|
+
<% end %>
|
@@ -0,0 +1,31 @@
|
|
1
|
+
<tr class="even:bg-gray-50 align-top">
|
2
|
+
<td scope="col" class="whitespace-wrap py-4 pl-4 pr-3 font-medium text-gray-900 sm:pl-3">
|
3
|
+
<div>
|
4
|
+
<%= error.emoji %>
|
5
|
+
<%= link_to error_path(error), class: "text-blue-400 underline inline-flex items-baseline gap-1" do %>
|
6
|
+
<strong><code><%= error.exception_class %></code></strong>
|
7
|
+
<% end %>
|
8
|
+
from
|
9
|
+
<em><code><%= error.source %></code></em>
|
10
|
+
</div>
|
11
|
+
<pre class="whitespace-pre-wrap ml-6 mt-4"><%= error.message %></pre>
|
12
|
+
</td>
|
13
|
+
<td scope="col" class="whitespace-nowrap px-3 py-4 pt-7 text-gray-500 text-right">
|
14
|
+
<%= error.occurrences_count %>
|
15
|
+
</td>
|
16
|
+
<td scope="col" class="whitespace-nowrap px-3 py-4 pt-7 text-gray-500 text-right">
|
17
|
+
<% last_seen_at = DateTime.strptime(error.recent_occurrence, "%Y-%m-%d %H:%M:%S.%N") %>
|
18
|
+
<abbr title="<%= last_seen_at.iso8601 %>" class="cursor-help">
|
19
|
+
<%= time_tag last_seen_at, time_ago_in_words(last_seen_at, scope: 'datetime.distance_in_words.short') %>
|
20
|
+
</abbr>
|
21
|
+
</td>
|
22
|
+
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-3">
|
23
|
+
<%= button_to error_path(error), method: :patch, class: "inline-flex items-center justify-center gap-2 font-medium cursor-pointer border rounded-lg py-3 px-5 bg-transparent text-blue-500 border-blue-500 hover:ring-blue-200 hover:ring-8", params: { error: { resolved_at: Time.now } } do %>
|
24
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="bi bi-check2-circle" viewBox="0 0 16 16">
|
25
|
+
<path d="M2.5 8a5.5 5.5 0 0 1 8.25-4.764.5.5 0 0 0 .5-.866A6.5 6.5 0 1 0 14.5 8a.5.5 0 0 0-1 0 5.5 5.5 0 1 1-11 0"/>
|
26
|
+
<path d="M15.354 3.354a.5.5 0 0 0-.708-.708L8 9.293 5.354 6.646a.5.5 0 1 0-.708.708l3 3a.5.5 0 0 0 .708 0z"/>
|
27
|
+
</svg>
|
28
|
+
<span>Resolve<span class="sr-only">, Error #<%= error.id %></span></span>
|
29
|
+
<% end %>
|
30
|
+
</td>
|
31
|
+
</tr>
|
@@ -1,107 +1,11 @@
|
|
1
|
-
<%=
|
2
|
-
|
3
|
-
|
4
|
-
<%= @error.emoji %>
|
5
|
-
<code><%= @error.exception_class %></code>
|
6
|
-
from
|
7
|
-
<em><code><%= @error.source %></code></em>
|
8
|
-
<% end %>
|
9
|
-
|
10
|
-
<small class="text-base">
|
11
|
-
#<code><%= @error.id %></code>
|
12
|
-
</small>
|
13
|
-
</div>
|
14
|
-
|
15
|
-
<pre class=""><%= @error.message %></pre>
|
16
|
-
|
17
|
-
<dl class="flex-1 grid grid-cols-2 gap-x-4">
|
18
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
19
|
-
<dt class="font-bold">
|
20
|
-
<%= SolidErrors::Error.human_attribute_name(:first_seen) %>
|
21
|
-
</dt>
|
22
|
-
<dd class="inline-flex items-center gap-1">
|
23
|
-
<% first_seen_at = @error.occurrences.minimum(:created_at) %>
|
24
|
-
|
25
|
-
<abbr title="<%= first_seen_at.iso8601 %>" class="cursor-help">
|
26
|
-
<%= time_tag first_seen_at, "#{time_ago_in_words(first_seen_at)} ago" %>
|
27
|
-
</abbr>
|
28
|
-
</dd>
|
29
|
-
</div>
|
30
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
31
|
-
<dt class="font-bold">
|
32
|
-
<%= SolidErrors::Error.human_attribute_name(:last_seen) %>
|
33
|
-
</dt>
|
34
|
-
<dd class="inline-flex items-center gap-1">
|
35
|
-
<% last_seen_at = @error.occurrences.maximum(:created_at) %>
|
36
|
-
|
37
|
-
<abbr title="<%= last_seen_at.iso8601 %>" class="cursor-help">
|
38
|
-
<%= time_tag last_seen_at, "#{time_ago_in_words(last_seen_at)} ago" %>
|
39
|
-
</abbr>
|
40
|
-
</dd>
|
41
|
-
</div>
|
42
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
43
|
-
<dt class="font-bold">
|
44
|
-
<%= SolidErrors::Error.human_attribute_name(:occurrences) %>
|
45
|
-
</dt>
|
46
|
-
<dd class="inline-flex items-center gap-1">
|
47
|
-
<%= @error.occurrences.size %>
|
48
|
-
</dd>
|
49
|
-
</div>
|
50
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
51
|
-
<dt class="font-bold">
|
52
|
-
<%= SolidErrors::Error.human_attribute_name(:exception_class) %>
|
53
|
-
</dt>
|
54
|
-
<dd class="inline-flex items-center gap-1">
|
55
|
-
<code><%= @error.exception_class %></code>
|
56
|
-
</dd>
|
57
|
-
</div>
|
58
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
59
|
-
<dt class="font-bold">
|
60
|
-
<%= SolidErrors::Error.human_attribute_name(:severity) %>
|
61
|
-
</dt>
|
62
|
-
<dd class="inline-flex items-center gap-1">
|
63
|
-
<%= @error.emoji %>
|
64
|
-
<span class="<%= @error.badge_classes %>">
|
65
|
-
<%= @error.severity %>
|
66
|
-
</span>
|
67
|
-
</dd>
|
68
|
-
</div>
|
69
|
-
<div class="flex items-center justify-between flex-wrap gap-x-2">
|
70
|
-
<dt class="font-bold">
|
71
|
-
<%= SolidErrors::Error.human_attribute_name(:source) %>
|
72
|
-
</dt>
|
73
|
-
<dd class="inline-flex items-center gap-1">
|
74
|
-
<em><%= @error.source %></em>
|
75
|
-
</dd>
|
76
|
-
</div>
|
77
|
-
<div class="flex items-start justify-between flex-wrap gap-x-2">
|
78
|
-
<dt class="font-bold">
|
79
|
-
<%= SolidErrors::Error.human_attribute_name(:project_root) %>
|
80
|
-
</dt>
|
81
|
-
<dd class="">
|
82
|
-
<span><%= SolidErrors::BacktraceLine::RAILS_ROOT %></span>
|
83
|
-
</dd>
|
84
|
-
</div>
|
85
|
-
<div class="flex items-start justify-between flex-wrap gap-x-2">
|
86
|
-
<dt class="font-bold">
|
87
|
-
<%= SolidErrors::Error.human_attribute_name(:gem_root) %>
|
88
|
-
</dt>
|
89
|
-
<dd class="">
|
90
|
-
<ul>
|
91
|
-
<% Gem.path.each do |path| %>
|
92
|
-
<li><%= path %></li>
|
93
|
-
<% end %>
|
94
|
-
</ul>
|
95
|
-
</dd>
|
96
|
-
</div>
|
97
|
-
</dl>
|
98
|
-
|
99
|
-
<%= render "solid_errors/errors/actions", error: @error %>
|
100
|
-
<% end %>
|
1
|
+
<%= render "solid_errors/errors/error",
|
2
|
+
error: @error,
|
3
|
+
show_actions: true %>
|
101
4
|
|
102
5
|
<br>
|
103
6
|
<br>
|
104
7
|
|
105
8
|
<%= render "solid_errors/occurrences/collection",
|
106
|
-
occurrences: @
|
9
|
+
occurrences: @occurrences,
|
10
|
+
page: @page,
|
107
11
|
titled: true %>
|
@@ -6,9 +6,44 @@
|
|
6
6
|
<h2 class="font-bold text-2xl">
|
7
7
|
Occurrences
|
8
8
|
</h2>
|
9
|
-
<
|
10
|
-
|
11
|
-
|
9
|
+
<div class="flex gap-x-4 pb-2">
|
10
|
+
<p class="text-right">
|
11
|
+
<% page_count = page.count %>
|
12
|
+
<% if page_count.zero? %>
|
13
|
+
No posts found
|
14
|
+
<% elsif page.pages == 1 %>
|
15
|
+
<strong><%= page_count %></strong> total
|
16
|
+
<% else %>
|
17
|
+
<strong><%= page.from %>-<%= page.to %></strong> of <strong><%= page_count %></strong>
|
18
|
+
<% end %>
|
19
|
+
</p>
|
20
|
+
|
21
|
+
<nav aria-label="Pages">
|
22
|
+
<% if (first_page = page.first) %>
|
23
|
+
<a href="<%= url_for(params.to_unsafe_hash.merge(page: first_page)) %>" aria-label="First" class="border border-black text-black bg-white py-1 px-2 cursor-pointer hover:bg-black hover:text-white">«</a>
|
24
|
+
<% else %>
|
25
|
+
<a role="link" aria-disabled="true" aria-label="First" class="border text-gray-500 bg-white py-1 px-2">«</a>
|
26
|
+
<% end %>
|
27
|
+
|
28
|
+
<% if (prev_page = page.prev) %>
|
29
|
+
<a href="<%= url_for(params.to_unsafe_hash.merge(page: prev_page)) %>" aria-label="Previous" class="border border-black text-black bg-white py-1 px-2 cursor-pointer hover:bg-black hover:text-white">‹</a>
|
30
|
+
<% else %>
|
31
|
+
<a role="link" aria-disabled="true" aria-label="Previous" class="border text-gray-500 bg-white py-1 px-2">‹</a>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<% if (next_page = page.next) %>
|
35
|
+
<a href="<%= url_for(params.to_unsafe_hash.merge(page: next_page)) %>" aria-label="Next" class="border border-black text-black bg-white py-1 px-2 cursor-pointer hover:bg-black hover:text-white">›</a>
|
36
|
+
<% else %>
|
37
|
+
<a role="link" aria-disabled="true" aria-label="Next" class="border text-gray-500 bg-white py-1 px-2">›</a>
|
38
|
+
<% end %>
|
39
|
+
|
40
|
+
<% if (last_page = page.last) %>
|
41
|
+
<a href="<%= url_for(params.to_unsafe_hash.merge(page: last_page)) %>" aria-label="Last" class="border border-black text-black bg-white py-1 px-2 cursor-pointer hover:bg-black hover:text-white">»</a>
|
42
|
+
<% else %>
|
43
|
+
<a role="link" aria-disabled="true" aria-label="Last" class="border text-gray-500 bg-white py-1 px-2">»</a>
|
44
|
+
<% end %>
|
45
|
+
</nav>
|
46
|
+
</div>
|
12
47
|
</div>
|
13
48
|
<% end %>
|
14
49
|
|
@@ -1,8 +1,9 @@
|
|
1
1
|
<% seen_at = occurrence.created_at %>
|
2
2
|
<% backtrace = occurrence.parsed_backtrace %>
|
3
|
+
<% open ||= defined?(occurrence_counter) ? occurrence_counter.zero? : true %>
|
3
4
|
|
4
5
|
<%= tag.section id: dom_id(occurrence), class: "" do %>
|
5
|
-
<%= tag.details open:
|
6
|
+
<%= tag.details open: open do %>
|
6
7
|
<summary class="hover:bg-gray-50 p-2 rounded cursor-pointer">
|
7
8
|
<%= time_tag seen_at, seen_at %>
|
8
9
|
(<em><%= time_ago_in_words(seen_at) %> ago</em>)
|
@@ -3,15 +3,14 @@
|
|
3
3
|
class CreateSolidErrorsTables < ActiveRecord::Migration<%= migration_version %>
|
4
4
|
def change
|
5
5
|
create_table :solid_errors do |t|
|
6
|
-
t.
|
7
|
-
t.
|
8
|
-
t.
|
9
|
-
t.
|
6
|
+
t.text :exception_class, null: false
|
7
|
+
t.text :message, null: false
|
8
|
+
t.text :severity, null: false
|
9
|
+
t.text :source
|
10
10
|
t.datetime :resolved_at, index: true
|
11
|
+
t.string :fingerprint, null: false, limit: 64, index: { unique: true }
|
11
12
|
|
12
13
|
t.timestamps
|
13
|
-
|
14
|
-
t.index [:exception_class, :message, :severity, :source], unique: true, name: "solid_error_uniqueness_index"
|
15
14
|
end
|
16
15
|
|
17
16
|
create_table :solid_errors_occurrences do |t|
|
data/lib/solid_errors/engine.rb
CHANGED
@@ -30,10 +30,11 @@ module SolidErrors
|
|
30
30
|
severity: severity,
|
31
31
|
source: source
|
32
32
|
}
|
33
|
-
|
33
|
+
fingerprint = Digest::SHA256.hexdigest(error_attributes.values.join)
|
34
|
+
if (record = SolidErrors::Error.find_by(fingerprint: fingerprint))
|
34
35
|
record.update!(resolved_at: nil, updated_at: Time.now)
|
35
36
|
else
|
36
|
-
record = SolidErrors::Error.create!(error_attributes)
|
37
|
+
record = SolidErrors::Error.create!(error_attributes.merge(fingerprint: fingerprint))
|
37
38
|
end
|
38
39
|
|
39
40
|
SolidErrors::Occurrence.create(
|
data/lib/solid_errors/version.rb
CHANGED
data/lib/solid_errors.rb
CHANGED
@@ -9,6 +9,9 @@ module SolidErrors
|
|
9
9
|
mattr_accessor :connects_to
|
10
10
|
mattr_writer :username
|
11
11
|
mattr_writer :password
|
12
|
+
mattr_writer :send_emails
|
13
|
+
mattr_writer :email_from
|
14
|
+
mattr_writer :email_to
|
12
15
|
|
13
16
|
class << self
|
14
17
|
# use method instead of attr_accessor to ensure
|
@@ -22,5 +25,17 @@ module SolidErrors
|
|
22
25
|
def password
|
23
26
|
@password ||= ENV["SOLIDERRORS_PASSWORD"] || @@password
|
24
27
|
end
|
28
|
+
|
29
|
+
def send_emails?
|
30
|
+
@send_emails ||= ENV["SOLIDERRORS_SEND_EMAILS"] || @@send_emails || true
|
31
|
+
end
|
32
|
+
|
33
|
+
def email_from
|
34
|
+
@email_from ||= ENV["SOLIDERRORS_EMAIL_FROM"] || @@email_from || "solid_errors@noreply.com"
|
35
|
+
end
|
36
|
+
|
37
|
+
def email_to
|
38
|
+
@email_to ||= ENV["SOLIDERRORS_EMAIL_TO"] || @@email_to
|
39
|
+
end
|
25
40
|
end
|
26
41
|
end
|
metadata
CHANGED
@@ -1,17 +1,87 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: solid_errors
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen Margheim
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-04-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: actionmailer
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '7.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '7.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: actionpack
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '7.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '7.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: actionview
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '7.0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '7.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activerecord
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '7.0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '7.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: activesupport
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '7.0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '7.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: railties
|
15
85
|
requirement: !ruby/object:Gem::Requirement
|
16
86
|
requirements:
|
17
87
|
- - "~>"
|
@@ -49,15 +119,19 @@ files:
|
|
49
119
|
- Rakefile
|
50
120
|
- app/controllers/solid_errors/application_controller.rb
|
51
121
|
- app/controllers/solid_errors/errors_controller.rb
|
122
|
+
- app/mailers/solid_errors/error_mailer.rb
|
52
123
|
- app/models/solid_errors/backtrace.rb
|
53
124
|
- app/models/solid_errors/backtrace_line.rb
|
54
125
|
- app/models/solid_errors/error.rb
|
55
126
|
- app/models/solid_errors/occurrence.rb
|
56
127
|
- app/models/solid_errors/record.rb
|
128
|
+
- app/views/layouts/solid_errors/_style.html
|
57
129
|
- app/views/layouts/solid_errors/application.html.erb
|
130
|
+
- app/views/solid_errors/error_mailer/error_occurred.html.erb
|
58
131
|
- app/views/solid_errors/error_mailer/error_occurred.text.erb
|
59
132
|
- app/views/solid_errors/errors/_actions.html.erb
|
60
133
|
- app/views/solid_errors/errors/_error.html.erb
|
134
|
+
- app/views/solid_errors/errors/_row.html.erb
|
61
135
|
- app/views/solid_errors/errors/index.html.erb
|
62
136
|
- app/views/solid_errors/errors/show.html.erb
|
63
137
|
- app/views/solid_errors/occurrences/_collection.html.erb
|