error_radar 0.6.0 → 0.7.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/CHANGELOG.md +31 -0
- data/app/controllers/error_radar/api/errors_controller.rb +16 -0
- data/app/controllers/error_radar/errors_controller.rb +17 -1
- data/app/models/error_radar/error_log.rb +15 -0
- data/app/models/error_radar/error_occurrence.rb +41 -0
- data/app/views/error_radar/errors/show.html.erb +96 -0
- data/lib/error_radar/configuration.rb +11 -0
- data/lib/error_radar/version.rb +1 -1
- data/lib/generators/error_radar/install/templates/initializer.rb +6 -0
- data/lib/generators/error_radar/upgrade_v060/templates/create_error_radar_occurrences.rb.tt +24 -0
- data/lib/generators/error_radar/upgrade_v060/upgrade_v060_generator.rb +20 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 57b3fa6a7576ae08baeb699b180048363846c84ecbb489fc93e16ea537939898
|
|
4
|
+
data.tar.gz: 67008613bd52755dad89b7ed1abbc9a86eb92c138f95cae8005f5272e8336594
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 2882f7be2a07a38bdafd4b44c8251774a470f37d44fcd3dc4403046cd2998eb1077ac576c97cd8aed6a43ab4a86153440598bafa5a6a47576f06bbc137a2528d
|
|
7
|
+
data.tar.gz: 8717757580e628dc988422df68c3a806bd7d9727f297439b5e7303cc049a48371f37035442dbfd12f7789cb8b480221b093720dda965f6ebeffc2c75ef3bcb57
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,37 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [0.7.0] - 2026-07-03
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- **Occurrence history**: every individual error hit can now be stored in a
|
|
9
|
+
separate `error_radar_occurrences` table. Enable with
|
|
10
|
+
`config.track_occurrences = true` after running the upgrade migration:
|
|
11
|
+
`bin/rails generate error_radar:upgrade_v060 && bin/rails db:migrate`.
|
|
12
|
+
- **`ErrorRadar::ErrorOccurrence` model**: columns `occurred_at`, `context`,
|
|
13
|
+
`backtrace`, `http_status`, `request_url`. Belongs to `ErrorLog` via
|
|
14
|
+
`error_log_id`. Indexed on `(error_log_id, occurred_at)` for fast retrieval.
|
|
15
|
+
- **`config.max_occurrences_per_error`** (default: 200): automatically prunes
|
|
16
|
+
the oldest occurrences for a given error on each new hit so the table stays
|
|
17
|
+
bounded without manual cleanup.
|
|
18
|
+
- **Occurrences panel on error detail page**: shows the 20 most recent
|
|
19
|
+
occurrences with timestamp, HTTP status badge, request URL, and expandable
|
|
20
|
+
"Context" / "Stack" toggles. Paginated at 20 per page.
|
|
21
|
+
- **`GET /api/errors/:id`** now includes `recent_occurrences` (last 10 hits
|
|
22
|
+
with `occurred_at`, `http_status`, `request_url`, `context`) when
|
|
23
|
+
`track_occurrences` is enabled.
|
|
24
|
+
- **`error_radar:upgrade_v060` generator**: generates the migration that creates
|
|
25
|
+
`error_radar_occurrences`.
|
|
26
|
+
- **`ErrorLog#occurrences`** association: `has_many :occurrences, dependent: :delete_all`
|
|
27
|
+
so destroying an error log also removes its occurrence history.
|
|
28
|
+
|
|
29
|
+
### Notes
|
|
30
|
+
- `track_occurrences` defaults to `false` to avoid unexpected writes before the
|
|
31
|
+
migration is run. Set it to `true` after the migration has been applied.
|
|
32
|
+
- Occurrences are recorded via `ErrorLog.record`, which is called by both the
|
|
33
|
+
synchronous capture path and `CaptureJob` (async path) — no extra
|
|
34
|
+
configuration needed once enabled.
|
|
35
|
+
|
|
5
36
|
## [0.6.0] - 2026-07-03
|
|
6
37
|
|
|
7
38
|
### Added
|
|
@@ -99,6 +99,22 @@ module ErrorRadar
|
|
|
99
99
|
context: log.context,
|
|
100
100
|
backtrace: log.backtrace
|
|
101
101
|
)
|
|
102
|
+
|
|
103
|
+
if ErrorRadar.config.track_occurrences
|
|
104
|
+
begin
|
|
105
|
+
data[:recent_occurrences] = log.occurrences.recent.limit(10).map do |occ|
|
|
106
|
+
{
|
|
107
|
+
id: occ.id,
|
|
108
|
+
occurred_at: occ.occurred_at&.iso8601,
|
|
109
|
+
http_status: occ.http_status,
|
|
110
|
+
request_url: occ.request_url,
|
|
111
|
+
context: occ.context
|
|
112
|
+
}
|
|
113
|
+
end
|
|
114
|
+
rescue ActiveRecord::StatementInvalid
|
|
115
|
+
data[:recent_occurrences] = []
|
|
116
|
+
end
|
|
117
|
+
end
|
|
102
118
|
end
|
|
103
119
|
|
|
104
120
|
if log.class.column_names.include?('github_issue_url')
|
|
@@ -22,7 +22,23 @@ module ErrorRadar
|
|
|
22
22
|
@pages = pagination_pages(@page, @total_pages)
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
def show
|
|
25
|
+
def show
|
|
26
|
+
@occurrences = []
|
|
27
|
+
return unless ErrorRadar.config.track_occurrences
|
|
28
|
+
|
|
29
|
+
begin
|
|
30
|
+
@occ_page = [params[:occ_page].to_i, 1].max
|
|
31
|
+
occ_per_page = 20
|
|
32
|
+
@occ_total = @error.occurrences.count
|
|
33
|
+
@occ_total_pages = [(@occ_total.to_f / occ_per_page).ceil, 1].max
|
|
34
|
+
@occ_page = [@occ_page, @occ_total_pages].min
|
|
35
|
+
@occurrences = @error.occurrences.recent
|
|
36
|
+
.limit(occ_per_page)
|
|
37
|
+
.offset((@occ_page - 1) * occ_per_page)
|
|
38
|
+
rescue ActiveRecord::StatementInvalid
|
|
39
|
+
@occurrences = []
|
|
40
|
+
end
|
|
41
|
+
end
|
|
26
42
|
|
|
27
43
|
def update_status
|
|
28
44
|
new_status = params[:status].to_s
|
|
@@ -16,6 +16,10 @@ module ErrorRadar
|
|
|
16
16
|
|
|
17
17
|
enum status: { open: 0, in_progress: 1, resolved: 2, ignored: 3 }, _prefix: :status
|
|
18
18
|
|
|
19
|
+
has_many :occurrences, class_name: 'ErrorRadar::ErrorOccurrence',
|
|
20
|
+
foreign_key: :error_log_id,
|
|
21
|
+
dependent: :delete_all
|
|
22
|
+
|
|
19
23
|
validates :fingerprint, presence: true, uniqueness: true
|
|
20
24
|
validates :first_seen_at, :last_seen_at, presence: true
|
|
21
25
|
|
|
@@ -60,6 +64,17 @@ module ErrorRadar
|
|
|
60
64
|
log.last_seen_at = now
|
|
61
65
|
log.save!
|
|
62
66
|
log.instance_variable_set(:@new_fingerprint, new_fingerprint)
|
|
67
|
+
|
|
68
|
+
if ErrorRadar.config.track_occurrences
|
|
69
|
+
ErrorRadar::ErrorOccurrence.record_for(
|
|
70
|
+
log,
|
|
71
|
+
context: context,
|
|
72
|
+
backtrace: backtrace,
|
|
73
|
+
http_status: http_status,
|
|
74
|
+
request_url: request_url
|
|
75
|
+
)
|
|
76
|
+
end
|
|
77
|
+
|
|
63
78
|
log
|
|
64
79
|
rescue StandardError => e
|
|
65
80
|
ErrorRadar::Tracking.warn_internal("ErrorLog.record failed: #{e.class}: #{e.message}")
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ErrorRadar
|
|
4
|
+
# One row per individual error hit. Linked to an ErrorLog (the deduplicated
|
|
5
|
+
# aggregate). Only recorded when config.track_occurrences is true and the
|
|
6
|
+
# upgrade_v060 migration has been run.
|
|
7
|
+
class ErrorOccurrence < ApplicationRecord
|
|
8
|
+
belongs_to :error_log
|
|
9
|
+
|
|
10
|
+
scope :recent, -> { order(occurred_at: :desc) }
|
|
11
|
+
|
|
12
|
+
def self.record_for(log, context: {}, backtrace: nil, http_status: nil, request_url: nil)
|
|
13
|
+
max = ErrorRadar.config.max_occurrences_per_error
|
|
14
|
+
|
|
15
|
+
create!(
|
|
16
|
+
error_log: log,
|
|
17
|
+
occurred_at: Time.current,
|
|
18
|
+
context: context.presence,
|
|
19
|
+
backtrace: Array(backtrace).join("\n").presence,
|
|
20
|
+
http_status: http_status,
|
|
21
|
+
request_url: request_url
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if max&.positive?
|
|
25
|
+
keep_ids = where(error_log_id: log.id).order(occurred_at: :desc).limit(max).pluck(:id)
|
|
26
|
+
where(error_log_id: log.id).where.not(id: keep_ids).delete_all if keep_ids.any?
|
|
27
|
+
end
|
|
28
|
+
rescue ActiveRecord::StatementInvalid
|
|
29
|
+
# Table not yet created — run: bin/rails generate error_radar:upgrade_v060 && bin/rails db:migrate
|
|
30
|
+
rescue StandardError => e
|
|
31
|
+
ErrorRadar::Tracking.warn_internal("ErrorOccurrence.record_for failed: #{e.class}: #{e.message}")
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def context_pretty
|
|
35
|
+
return '{}' if context.blank?
|
|
36
|
+
JSON.pretty_generate(context.is_a?(Hash) ? context : JSON.parse(context.to_s))
|
|
37
|
+
rescue JSON::ParserError
|
|
38
|
+
context.to_s
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -104,6 +104,97 @@
|
|
|
104
104
|
</div>
|
|
105
105
|
</div>
|
|
106
106
|
|
|
107
|
+
<%# ── Occurrences History ── %>
|
|
108
|
+
<% if ErrorRadar.config.track_occurrences %>
|
|
109
|
+
<div class="panel" style="margin-top:16px" id="occurrences-panel">
|
|
110
|
+
<div style="display:flex;justify-content:space-between;align-items:baseline;margin-bottom:12px">
|
|
111
|
+
<h2 style="margin:0">Occurrence History
|
|
112
|
+
<% if @occ_total.to_i > 0 %>
|
|
113
|
+
<span style="font-size:13px;font-weight:400;color:#6b7280">(<%= @occ_total %> total)</span>
|
|
114
|
+
<% end %>
|
|
115
|
+
</h2>
|
|
116
|
+
</div>
|
|
117
|
+
|
|
118
|
+
<% if @occurrences.empty? %>
|
|
119
|
+
<p style="font-size:13px;color:#9ca3af;margin:0">
|
|
120
|
+
<% if @occ_total.to_i == 0 %>
|
|
121
|
+
No occurrences recorded yet. New hits will appear here.
|
|
122
|
+
<% else %>
|
|
123
|
+
No occurrences on this page.
|
|
124
|
+
<% end %>
|
|
125
|
+
</p>
|
|
126
|
+
<% else %>
|
|
127
|
+
<table style="width:100%;border-collapse:collapse;font-size:13px">
|
|
128
|
+
<thead>
|
|
129
|
+
<tr style="border-bottom:2px solid #e5e7eb">
|
|
130
|
+
<th style="text-align:left;padding:6px 8px;color:#6b7280;width:170px">Time</th>
|
|
131
|
+
<th style="text-align:left;padding:6px 8px;color:#6b7280;width:70px">HTTP</th>
|
|
132
|
+
<th style="text-align:left;padding:6px 8px;color:#6b7280">Context / Request</th>
|
|
133
|
+
<th style="text-align:left;padding:6px 8px;color:#6b7280;width:80px">Backtrace</th>
|
|
134
|
+
</tr>
|
|
135
|
+
</thead>
|
|
136
|
+
<tbody>
|
|
137
|
+
<% @occurrences.each_with_index do |occ, i| %>
|
|
138
|
+
<tr style="border-bottom:1px solid #f3f4f6" class="occ-row">
|
|
139
|
+
<td style="padding:7px 8px;font-family:monospace;font-size:11px;white-space:nowrap">
|
|
140
|
+
<%= occ.occurred_at&.strftime('%Y-%m-%d %H:%M:%S') %>
|
|
141
|
+
</td>
|
|
142
|
+
<td style="padding:7px 8px">
|
|
143
|
+
<% if occ.http_status.present? %>
|
|
144
|
+
<span class="badge" style="background:<%= occ.http_status.to_i >= 500 ? '#dc3545' : '#fd7e14' %>">
|
|
145
|
+
<%= occ.http_status %>
|
|
146
|
+
</span>
|
|
147
|
+
<% end %>
|
|
148
|
+
</td>
|
|
149
|
+
<td style="padding:7px 8px;max-width:400px">
|
|
150
|
+
<% if occ.request_url.present? %>
|
|
151
|
+
<div style="font-size:11px;color:#6b7280;word-break:break-all;margin-bottom:4px"><%= occ.request_url.truncate(120) %></div>
|
|
152
|
+
<% end %>
|
|
153
|
+
<% unless (occ.context || {}).empty? %>
|
|
154
|
+
<button onclick="toggleOcc('ctx-<%= i %>')"
|
|
155
|
+
style="padding:2px 8px;font-size:11px;border:1px solid #d1d5db;border-radius:4px;background:#f9fafb;cursor:pointer">
|
|
156
|
+
Context ▾
|
|
157
|
+
</button>
|
|
158
|
+
<div id="ctx-<%= i %>" style="display:none;margin-top:6px">
|
|
159
|
+
<pre class="er-pre" style="max-height:200px;font-size:10px"><%= occ.context_pretty %></pre>
|
|
160
|
+
</div>
|
|
161
|
+
<% end %>
|
|
162
|
+
</td>
|
|
163
|
+
<td style="padding:7px 8px">
|
|
164
|
+
<% if occ.backtrace.present? %>
|
|
165
|
+
<button onclick="toggleOcc('bt-<%= i %>')"
|
|
166
|
+
style="padding:2px 8px;font-size:11px;border:1px solid #d1d5db;border-radius:4px;background:#f9fafb;cursor:pointer">
|
|
167
|
+
Stack ▾
|
|
168
|
+
</button>
|
|
169
|
+
<div id="bt-<%= i %>" style="display:none;position:absolute;z-index:10;background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:12px;width:600px;max-width:90vw;box-shadow:0 4px 16px rgba(0,0,0,.12)">
|
|
170
|
+
<pre class="er-pre" style="max-height:300px"><%= occ.backtrace %></pre>
|
|
171
|
+
<button onclick="toggleOcc('bt-<%= i %>')" style="margin-top:6px;font-size:11px;border:0;background:none;cursor:pointer;color:#6b7280">Close</button>
|
|
172
|
+
</div>
|
|
173
|
+
<% end %>
|
|
174
|
+
</td>
|
|
175
|
+
</tr>
|
|
176
|
+
<% end %>
|
|
177
|
+
</tbody>
|
|
178
|
+
</table>
|
|
179
|
+
|
|
180
|
+
<%# Pagination %>
|
|
181
|
+
<% if @occ_total_pages.to_i > 1 %>
|
|
182
|
+
<div style="margin-top:12px;display:flex;gap:6px;font-size:12px;align-items:center">
|
|
183
|
+
<% (1..@occ_total_pages).each do |p| %>
|
|
184
|
+
<% if p == @occ_page %>
|
|
185
|
+
<span style="padding:4px 10px;background:#2563eb;color:#fff;border-radius:6px"><%= p %></span>
|
|
186
|
+
<% else %>
|
|
187
|
+
<%= link_to p, error_path(@error, occ_page: p, anchor: 'occurrences-panel'),
|
|
188
|
+
style: 'padding:4px 10px;border:1px solid #d1d5db;border-radius:6px;text-decoration:none;color:#374151' %>
|
|
189
|
+
<% end %>
|
|
190
|
+
<% end %>
|
|
191
|
+
<span style="color:#9ca3af">of <%= @occ_total_pages %> pages</span>
|
|
192
|
+
</div>
|
|
193
|
+
<% end %>
|
|
194
|
+
<% end %>
|
|
195
|
+
</div>
|
|
196
|
+
<% end %>
|
|
197
|
+
|
|
107
198
|
<%# ── GitHub Issue ── %>
|
|
108
199
|
<% if ErrorRadar.config.github_token.present? && ErrorRadar.config.github_repo.present? %>
|
|
109
200
|
<div class="panel" style="margin-top:16px">
|
|
@@ -130,6 +221,11 @@
|
|
|
130
221
|
<% end %>
|
|
131
222
|
|
|
132
223
|
<script>
|
|
224
|
+
window.toggleOcc = function (id) {
|
|
225
|
+
var el = document.getElementById(id);
|
|
226
|
+
if (el) el.style.display = el.style.display === 'none' ? 'block' : 'none';
|
|
227
|
+
};
|
|
228
|
+
|
|
133
229
|
(function () {
|
|
134
230
|
var CSRF = document.querySelector('meta[name="csrf-token"]').content;
|
|
135
231
|
var STATUS_URL = '<%= error_status_path(@error) %>';
|
|
@@ -69,6 +69,14 @@ module ErrorRadar
|
|
|
69
69
|
@error_callbacks << block
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
+
# Occurrences ─────────────────────────────────────────────────────────────
|
|
73
|
+
# When true, each individual error hit is stored in error_radar_occurrences.
|
|
74
|
+
# Requires running: bin/rails generate error_radar:upgrade_v060 && bin/rails db:migrate
|
|
75
|
+
attr_accessor :track_occurrences
|
|
76
|
+
# Maximum occurrences to keep per ErrorLog. Oldest are pruned on each new hit.
|
|
77
|
+
# nil = keep all (not recommended for high-volume apps).
|
|
78
|
+
attr_accessor :max_occurrences_per_error
|
|
79
|
+
|
|
72
80
|
# Performance ─────────────────────────────────────────────────────────────
|
|
73
81
|
# When true, ErrorLog.record is enqueued via ActiveJob (non-blocking).
|
|
74
82
|
# Requires ActiveJob to be configured. Falls back to sync if ActiveJob is absent.
|
|
@@ -148,6 +156,9 @@ module ErrorRadar
|
|
|
148
156
|
@app_host = nil
|
|
149
157
|
@error_callbacks = []
|
|
150
158
|
|
|
159
|
+
@track_occurrences = false
|
|
160
|
+
@max_occurrences_per_error = 200
|
|
161
|
+
|
|
151
162
|
@async_capture = false
|
|
152
163
|
@capture_job_queue = :default
|
|
153
164
|
@retention_days = nil
|
data/lib/error_radar/version.rb
CHANGED
|
@@ -84,6 +84,12 @@ ErrorRadar.configure do |config|
|
|
|
84
84
|
# config.github_token = ENV['GITHUB_TOKEN'] # PAT with repo scope
|
|
85
85
|
# config.github_repo = 'myorg/myapp' # "owner/repo" format
|
|
86
86
|
|
|
87
|
+
# --- Occurrence History ---
|
|
88
|
+
# Store each individual error hit so you can see context/backtrace per occurrence.
|
|
89
|
+
# Requires running: bin/rails generate error_radar:upgrade_v060 && bin/rails db:migrate
|
|
90
|
+
# config.track_occurrences = true
|
|
91
|
+
# config.max_occurrences_per_error = 200 # keep last N per error (oldest pruned on each new hit)
|
|
92
|
+
|
|
87
93
|
# --- Performance & Async Capture ---
|
|
88
94
|
# Write ErrorLog records via ActiveJob so exceptions don't block the request.
|
|
89
95
|
# Requires ActiveJob + a queue adapter (Sidekiq, Solid Queue, etc.).
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
class CreateErrorRadarOccurrences < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
4
|
+
def change
|
|
5
|
+
create_table :error_radar_occurrences do |t|
|
|
6
|
+
t.references :error_log, null: false,
|
|
7
|
+
foreign_key: { to_table: :error_radar_error_logs },
|
|
8
|
+
index: false # covered by composite index below
|
|
9
|
+
|
|
10
|
+
t.datetime :occurred_at, null: false
|
|
11
|
+
|
|
12
|
+
t.json :context # structured payload snapshot for this hit
|
|
13
|
+
t.text :backtrace # backtrace at the moment of this occurrence
|
|
14
|
+
t.integer :http_status
|
|
15
|
+
t.string :request_url, limit: 2000
|
|
16
|
+
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Fast per-error chronological listing
|
|
21
|
+
add_index :error_radar_occurrences, %i[error_log_id occurred_at],
|
|
22
|
+
name: 'idx_er_occurrences_log_time'
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rails/generators/active_record'
|
|
4
|
+
|
|
5
|
+
module ErrorRadar
|
|
6
|
+
module Generators
|
|
7
|
+
class UpgradeV060Generator < ActiveRecord::Generators::Base
|
|
8
|
+
source_root File.expand_path('templates', __dir__)
|
|
9
|
+
|
|
10
|
+
argument :name, type: :string, default: 'upgrade_v060'
|
|
11
|
+
|
|
12
|
+
desc 'Creates the error_radar_occurrences table for per-hit occurrence history (v0.7.0).'
|
|
13
|
+
|
|
14
|
+
def create_migration
|
|
15
|
+
migration_template 'create_error_radar_occurrences.rb.tt',
|
|
16
|
+
'db/migrate/create_error_radar_occurrences.rb'
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: error_radar
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.7.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- chienbn9x
|
|
@@ -66,6 +66,7 @@ files:
|
|
|
66
66
|
- app/mailers/error_radar/error_mailer.rb
|
|
67
67
|
- app/models/error_radar/application_record.rb
|
|
68
68
|
- app/models/error_radar/error_log.rb
|
|
69
|
+
- app/models/error_radar/error_occurrence.rb
|
|
69
70
|
- app/views/error_radar/dashboard/index.html.erb
|
|
70
71
|
- app/views/error_radar/dashboard/show.html.erb
|
|
71
72
|
- app/views/error_radar/error_mailer/new_error.html.erb
|
|
@@ -98,6 +99,8 @@ files:
|
|
|
98
99
|
- lib/generators/error_radar/install/templates/initializer.rb
|
|
99
100
|
- lib/generators/error_radar/upgrade_v050/templates/add_github_issue_to_error_radar_error_logs.rb.tt
|
|
100
101
|
- lib/generators/error_radar/upgrade_v050/upgrade_v050_generator.rb
|
|
102
|
+
- lib/generators/error_radar/upgrade_v060/templates/create_error_radar_occurrences.rb.tt
|
|
103
|
+
- lib/generators/error_radar/upgrade_v060/upgrade_v060_generator.rb
|
|
101
104
|
- lib/tasks/error_radar.rake
|
|
102
105
|
homepage: https://github.com/chienbn9x/error_radar
|
|
103
106
|
licenses:
|