rails_error_dashboard 0.5.12 → 0.5.13

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2c512995247150c6d418591b4ea85b40778b37c5b484666cf2af2226cbad9da7
4
- data.tar.gz: 72283fdf63f2ea4fac3cdde62098bc247c4262862fbd8dd2ef80b5b804fcd626
3
+ metadata.gz: f0771a79dec323d80d0182e82dd4f5e9b9af6374a036baab00aa8b219c49ab38
4
+ data.tar.gz: 79facf6902dca535dae648469452b95f9fc093fe79b5f318790542384e6de4a1
5
5
  SHA512:
6
- metadata.gz: 5a66093c81993d0af82915235a2da1bbb5d0ba6779a9882d2e87bb90b4d98012d9d3f4be91703c570ac9253cd346d17f53a5eb8e21f9cc6bf44728e72ec23ef1
7
- data.tar.gz: '06290bf609e62810e613530eceff8dcc86936a8b39f7e27c5ac0b8bd2ba5090f05e2df7ed4b86f1ca6d732fa849cfeea6d3fd361f4ef79e9a304fd010239f8ad'
6
+ metadata.gz: d36de8595bd53ad2ec533d6d98fc7ba149b6dc218af477271daaa1f764456a72bdb64ac905090dfcc66749b6abfe833f983579890a7fbdaf254426549a61cc4a
7
+ data.tar.gz: 56729d084a67b300f231bb74a4108962a05c02ce73e97638dd9461464f14cc92e3085465e6645d69070e3b47f5281a3e081cd8cd8aa562ac3dfb373260a6b3a4
@@ -8,7 +8,7 @@ module RailsErrorDashboard
8
8
 
9
9
  mail(
10
10
  to: recipients,
11
- subject: "🚨 #{error_log.error_type}: #{truncate_subject(error_log.message)}"
11
+ subject: "🚨 [#{error_log.application&.name || 'Unknown'}] #{error_log.error_type}: #{truncate_subject(error_log.message)}"
12
12
  )
13
13
  end
14
14
 
@@ -133,6 +133,9 @@
133
133
 
134
134
  <div class="content">
135
135
  <div class="info-grid">
136
+ <div class="label">Application:</div>
137
+ <div class="value"><strong><%= @error_log.application&.name || 'Unknown' %></strong></div>
138
+
136
139
  <div class="label">Error Type:</div>
137
140
  <div class="value"><code><%= @error_log.error_type %></code></div>
138
141
 
@@ -2,6 +2,7 @@
2
2
  🚨 ERROR ALERT
3
3
  ==========================================
4
4
 
5
+ Application: <%= @error_log.application&.name || 'Unknown' %>
5
6
  Error Type: <%= @error_log.error_type %>
6
7
  <% if @error_log.platform.present? %>Platform: <%= @error_log.platform %><% end %>
7
8
  Occurred At: <%= @error_log.occurred_at.strftime('%B %d, %Y at %I:%M %p %Z') %>
@@ -2,7 +2,7 @@
2
2
  <td onclick="event.stopPropagation();">
3
3
  <input type="checkbox" class="error-checkbox form-check-input" value="<%= error.id %>" data-error-id="<%= error.id %>">
4
4
  </td>
5
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
5
+ <td onclick="window.location='<%= error_path(error) %>';">
6
6
  <% severity = error.severity %>
7
7
  <% if severity == :critical %>
8
8
  <span class="badge bg-danger" data-bs-toggle="tooltip" title="Critical severity - requires immediate attention">CRITICAL</span>
@@ -17,7 +17,7 @@
17
17
  <br><small class="text-muted" data-bs-toggle="tooltip" title="Priority score (0-100) based on severity, frequency, recency, and user impact">P<%= error.priority_score %></small>
18
18
  <% end %>
19
19
  </td>
20
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
20
+ <td onclick="window.location='<%= error_path(error) %>';">
21
21
  <code class="text-danger" data-bs-toggle="tooltip" title="<%= error.error_type %>"><%= error.error_type.split('::').last %></code>
22
22
  <% if error.recent? %>
23
23
  <span class="badge bg-success ms-1" data-bs-toggle="tooltip" title="Error occurred within the last hour">NEW</span>
@@ -26,29 +26,29 @@
26
26
  <br><small class="badge bg-light text-dark" data-bs-toggle="tooltip" title="App version when error occurred">v<%= error.app_version %></small>
27
27
  <% end %>
28
28
  </td>
29
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
29
+ <td onclick="window.location='<%= error_path(error) %>';">
30
30
  <div class="text-truncate" style="max-width: 300px;" title="<%= error.message %>">
31
31
  <%= error.message %>
32
32
  </div>
33
33
  </td>
34
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
34
+ <td onclick="window.location='<%= error_path(error) %>';">
35
35
  <span class="badge bg-primary"><%= error.occurrence_count %>x</span>
36
36
  </td>
37
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
37
+ <td onclick="window.location='<%= error_path(error) %>';">
38
38
  <small>
39
39
  <strong>First:</strong> <%= local_time(error.first_seen_at, format: :short) %><br>
40
40
  <strong>Last:</strong> <%= local_time(error.last_seen_at, format: :short) %>
41
41
  </small>
42
42
  </td>
43
43
  <% if local_assigns[:show_application] %>
44
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
44
+ <td onclick="window.location='<%= error_path(error) %>';">
45
45
  <span class="badge bg-info">
46
46
  <%= error.application&.name || 'Unknown' %>
47
47
  </span>
48
48
  </td>
49
49
  <% end %>
50
50
  <% if local_assigns[:show_platform] %>
51
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
51
+ <td onclick="window.location='<%= error_path(error) %>';">
52
52
  <% if error.platform == 'iOS' %>
53
53
  <span class="badge badge-ios"><i class="bi bi-apple"></i> iOS</span>
54
54
  <% elsif error.platform == 'Android' %>
@@ -60,7 +60,7 @@
60
60
  <% end %>
61
61
  </td>
62
62
  <% end %>
63
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
63
+ <td onclick="window.location='<%= error_path(error) %>';">
64
64
  <% if error.user_id %>
65
65
  <small data-bs-toggle="tooltip" title="User affected by this error">User #<%= error.user_id %></small>
66
66
  <% if error.respond_to?(:user_impact_percentage) %>
@@ -73,7 +73,7 @@
73
73
  <small class="text-muted" data-bs-toggle="tooltip" title="No specific user affected">-</small>
74
74
  <% end %>
75
75
  </td>
76
- <td onclick="window.location='<%= rails_error_dashboard.error_path(error) %>';">
76
+ <td onclick="window.location='<%= error_path(error) %>';">
77
77
  <% if error.resolved? %>
78
78
  <i class="bi bi-check-circle-fill text-success"
79
79
  data-bs-toggle="tooltip"
@@ -95,7 +95,7 @@
95
95
  <% end %>
96
96
  </td>
97
97
  <td onclick="event.stopPropagation();">
98
- <%= link_to rails_error_dashboard.error_path(error), class: "btn btn-sm btn-outline-primary" do %>
98
+ <%= link_to error_path(error), class: "btn btn-sm btn-outline-primary" do %>
99
99
  <i class="bi bi-eye"></i>
100
100
  <% end %>
101
101
  </td>
@@ -44,6 +44,10 @@ module RailsErrorDashboard
44
44
  {
45
45
  type: "section",
46
46
  fields: [
47
+ {
48
+ type: "mrkdwn",
49
+ text: "*Application:*\n#{NotificationHelpers.app_name(error_log)}"
50
+ },
47
51
  {
48
52
  type: "mrkdwn",
49
53
  text: "*Error Type:*\n#{error_log.error_type}"
@@ -104,6 +108,7 @@ module RailsErrorDashboard
104
108
  title: "🚨 Baseline Anomaly Detected",
105
109
  color: anomaly_color(anomaly_data[:level]),
106
110
  fields: [
111
+ { name: "Application", value: NotificationHelpers.app_name(error_log), inline: true },
107
112
  { name: "Error Type", value: error_log.error_type, inline: true },
108
113
  { name: "Platform", value: error_log.platform, inline: true },
109
114
  { name: "Severity", value: anomaly_data[:level].to_s.upcase, inline: true },
@@ -129,6 +134,7 @@ module RailsErrorDashboard
129
134
  timestamp: Time.current.iso8601,
130
135
  error: {
131
136
  id: error_log.id,
137
+ application: NotificationHelpers.app_name(error_log),
132
138
  type: error_log.error_type,
133
139
  message: error_log.message,
134
140
  platform: error_log.platform,
@@ -26,6 +26,11 @@ module RailsErrorDashboard
26
26
  description: NotificationHelpers.truncate_message(error_log.message, 200),
27
27
  color: severity_color(error_log),
28
28
  fields: [
29
+ {
30
+ name: "Application",
31
+ value: NotificationHelpers.app_name(error_log),
32
+ inline: true
33
+ },
29
34
  {
30
35
  name: "Platform",
31
36
  value: error_log.platform || "Unknown",
@@ -9,6 +9,11 @@ module RailsErrorDashboard
9
9
  #
10
10
  # IMPORTANT: Broadcasting failures MUST NOT block error logging.
11
11
  # All public methods rescue exceptions and log them.
12
+ #
13
+ # NOTE: Turbo broadcasts render partials via ApplicationController.render,
14
+ # which is the HOST app's controller — engine route helpers (error_path, etc.)
15
+ # are NOT available there. We render via the engine's own controller renderer
16
+ # and pass pre-rendered HTML to the broadcast to ensure route helpers work.
12
17
  class ErrorBroadcaster
13
18
  # Broadcast a new error (prepend to error list + refresh stats)
14
19
  # @param error_log [ErrorLog] The newly created error
@@ -19,11 +24,13 @@ module RailsErrorDashboard
19
24
  platforms = ErrorLog.distinct.pluck(:platform).compact
20
25
  show_platform = platforms.size > 1
21
26
 
27
+ html = render_partial("rails_error_dashboard/errors/error_row",
28
+ error: error_log, show_platform: show_platform)
29
+
22
30
  Turbo::StreamsChannel.broadcast_prepend_to(
23
31
  "error_list",
24
32
  target: "error_list",
25
- partial: "rails_error_dashboard/errors/error_row",
26
- locals: { error: error_log, show_platform: show_platform }
33
+ html: html
27
34
  )
28
35
  broadcast_stats
29
36
  rescue => e
@@ -40,11 +47,13 @@ module RailsErrorDashboard
40
47
  platforms = ErrorLog.distinct.pluck(:platform).compact
41
48
  show_platform = platforms.size > 1
42
49
 
50
+ html = render_partial("rails_error_dashboard/errors/error_row",
51
+ error: error_log, show_platform: show_platform)
52
+
43
53
  Turbo::StreamsChannel.broadcast_replace_to(
44
54
  "error_list",
45
55
  target: "error_#{error_log.id}",
46
- partial: "rails_error_dashboard/errors/error_row",
47
- locals: { error: error_log, show_platform: show_platform }
56
+ html: html
48
57
  )
49
58
  broadcast_stats
50
59
  rescue => e
@@ -59,17 +68,28 @@ module RailsErrorDashboard
59
68
  stats = Queries::DashboardStats.call
60
69
  return unless stats.is_a?(Hash) && stats.present?
61
70
 
71
+ html = render_partial("rails_error_dashboard/errors/stats", stats: stats)
72
+
62
73
  Turbo::StreamsChannel.broadcast_replace_to(
63
74
  "error_list",
64
75
  target: "dashboard_stats",
65
- partial: "rails_error_dashboard/errors/stats",
66
- locals: { stats: stats }
76
+ html: html
67
77
  )
68
78
  rescue => e
69
79
  Rails.logger.error("[RailsErrorDashboard] Failed to broadcast stats update: #{e.class} - #{e.message}")
70
80
  Rails.logger.debug("[RailsErrorDashboard] Backtrace: #{e.backtrace&.first(3)&.join("\n")}")
71
81
  end
72
82
 
83
+ # Render a partial using the engine's controller renderer.
84
+ # This ensures engine route helpers (error_path, etc.) are available,
85
+ # unlike Turbo's default ApplicationController.render which uses the host app's context.
86
+ def self.render_partial(partial, **locals)
87
+ RailsErrorDashboard::ApplicationController.render(
88
+ partial: partial,
89
+ locals: locals
90
+ )
91
+ end
92
+
73
93
  # Check if broadcasting infrastructure is available
74
94
  # @return [Boolean]
75
95
  def self.available?
@@ -82,6 +82,13 @@ module RailsErrorDashboard
82
82
  {}
83
83
  end
84
84
 
85
+ # Application name for notifications
86
+ # @param error_log [ErrorLog] The error
87
+ # @return [String] Application name or "Unknown"
88
+ def app_name(error_log)
89
+ error_log.application&.name || "Unknown"
90
+ end
91
+
85
92
  # Error source description for PagerDuty
86
93
  # @param error_log [ErrorLog] The error
87
94
  # @return [String] Source description
@@ -18,13 +18,14 @@ module RailsErrorDashboard
18
18
  routing_key: routing_key,
19
19
  event_action: "trigger",
20
20
  payload: {
21
- summary: "Critical Error: #{error_log.error_type} in #{error_log.platform}",
21
+ summary: "[#{NotificationHelpers.app_name(error_log)}] Critical Error: #{error_log.error_type} in #{error_log.platform}",
22
22
  severity: "critical",
23
23
  source: NotificationHelpers.error_source(error_log),
24
24
  component: error_log.controller_name || "Unknown",
25
25
  group: error_log.error_type,
26
26
  class: error_log.error_type,
27
27
  custom_details: {
28
+ application: NotificationHelpers.app_name(error_log),
28
29
  message: error_log.message,
29
30
  controller: error_log.controller_name,
30
31
  action: error_log.action_name,
@@ -42,6 +42,10 @@ module RailsErrorDashboard
42
42
  {
43
43
  type: "section",
44
44
  fields: [
45
+ {
46
+ type: "mrkdwn",
47
+ text: "*Application:*\n#{NotificationHelpers.app_name(error_log)}"
48
+ },
45
49
  {
46
50
  type: "mrkdwn",
47
51
  text: "*Error Type:*\n`#{error_log.error_type}`"
@@ -18,6 +18,7 @@ module RailsErrorDashboard
18
18
  timestamp: Time.current.iso8601,
19
19
  error: {
20
20
  id: error_log.id,
21
+ application: NotificationHelpers.app_name(error_log),
21
22
  type: error_log.error_type,
22
23
  message: error_log.message,
23
24
  severity: error_log.severity.to_s,
@@ -1,3 +1,3 @@
1
1
  module RailsErrorDashboard
2
- VERSION = "0.5.12"
2
+ VERSION = "0.5.13"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_error_dashboard
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.12
4
+ version: 0.5.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Anjan Jagirdar
@@ -496,7 +496,7 @@ metadata:
496
496
  funding_uri: https://github.com/sponsors/AnjanJ
497
497
  post_install_message: |
498
498
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
499
- RED (Rails Error Dashboard) v0.5.12
499
+ RED (Rails Error Dashboard) v0.5.13
500
500
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
501
501
 
502
502
  First install: