rails_error_dashboard 0.1.19 → 0.1.20
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:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e25820931efde6d62173ac5455658d05799202e5a3b7bc745ee5368880079ef2
|
|
4
|
+
data.tar.gz: 9cfc00e8a78eb876d64a1908df201b05231d2ec1ff538c8bbda391198e7c1947
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: db9e01290004af02ae9a5b9f55039ddeec858f1761c9ec685be1e7a5ec91590f8ed4ca1b5a7c1a1b57babf1e6cfb1b394afcb70504175949c0c8480fc7cb47f3
|
|
7
|
+
data.tar.gz: 7c04e609a1b700c51d634f932f20ab1ed448603e9390141f5cd5ba78c86415fda2bb413ef457a73d290967da998407b7f51a3655f425b2833462472212dc97e5
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RailsErrorDashboard
|
|
4
|
+
# ManualErrorReporter: Report errors manually from frontend, mobile apps, or custom sources
|
|
5
|
+
#
|
|
6
|
+
# This class provides a clean API for logging errors that don't originate from Ruby exceptions,
|
|
7
|
+
# such as JavaScript errors from the frontend, mobile app crashes, or manually constructed errors.
|
|
8
|
+
#
|
|
9
|
+
# @example Frontend JavaScript error
|
|
10
|
+
# RailsErrorDashboard::ManualErrorReporter.report(
|
|
11
|
+
# error_type: "TypeError",
|
|
12
|
+
# message: "Cannot read property 'foo' of undefined",
|
|
13
|
+
# backtrace: ["at handleClick (app.js:42)", "at onClick (button.js:15)"],
|
|
14
|
+
# platform: "Web",
|
|
15
|
+
# user_id: current_user&.id,
|
|
16
|
+
# request_url: request.url,
|
|
17
|
+
# user_agent: request.user_agent,
|
|
18
|
+
# metadata: { component: "ShoppingCart", action: "checkout" }
|
|
19
|
+
# )
|
|
20
|
+
#
|
|
21
|
+
# @example Mobile app crash
|
|
22
|
+
# RailsErrorDashboard::ManualErrorReporter.report(
|
|
23
|
+
# error_type: "NSException",
|
|
24
|
+
# message: "Fatal crash in payment processing",
|
|
25
|
+
# backtrace: stacktrace_array,
|
|
26
|
+
# platform: "iOS",
|
|
27
|
+
# app_version: "2.1.0",
|
|
28
|
+
# user_id: user_id,
|
|
29
|
+
# metadata: { device: "iPhone 14", os_version: "17.2" }
|
|
30
|
+
# )
|
|
31
|
+
class ManualErrorReporter
|
|
32
|
+
# Report a manual error to the dashboard
|
|
33
|
+
#
|
|
34
|
+
# @param error_type [String] The error class/type (e.g., "TypeError", "NetworkError")
|
|
35
|
+
# @param message [String] The error message
|
|
36
|
+
# @param backtrace [Array<String>, String, nil] Stack trace as array of strings or newline-separated string
|
|
37
|
+
# @param platform [String, nil] Platform where error occurred ("Web", "iOS", "Android", "API")
|
|
38
|
+
# @param user_id [String, Integer, nil] ID of the user who experienced the error
|
|
39
|
+
# @param request_url [String, nil] URL where the error occurred
|
|
40
|
+
# @param user_agent [String, nil] User agent string
|
|
41
|
+
# @param ip_address [String, nil] IP address of the requester
|
|
42
|
+
# @param app_version [String, nil] Version of the app where error occurred
|
|
43
|
+
# @param metadata [Hash, nil] Additional custom metadata about the error
|
|
44
|
+
# @param occurred_at [Time, nil] When the error occurred (defaults to Time.current)
|
|
45
|
+
# @param severity [Symbol, nil] Severity level (:critical, :high, :medium, :low)
|
|
46
|
+
# @param source [String, nil] Source identifier (e.g., "frontend", "mobile_app")
|
|
47
|
+
#
|
|
48
|
+
# @return [ErrorLog, nil] The created error log record, or nil if filtered/ignored
|
|
49
|
+
#
|
|
50
|
+
# @example Basic usage
|
|
51
|
+
# ManualErrorReporter.report(
|
|
52
|
+
# error_type: "ValidationError",
|
|
53
|
+
# message: "Email format is invalid",
|
|
54
|
+
# platform: "Web"
|
|
55
|
+
# )
|
|
56
|
+
#
|
|
57
|
+
# @example With full context
|
|
58
|
+
# ManualErrorReporter.report(
|
|
59
|
+
# error_type: "PaymentError",
|
|
60
|
+
# message: "Credit card declined",
|
|
61
|
+
# backtrace: ["checkout.js:123", "payment.js:45"],
|
|
62
|
+
# platform: "Web",
|
|
63
|
+
# user_id: current_user.id,
|
|
64
|
+
# request_url: checkout_url,
|
|
65
|
+
# user_agent: request.user_agent,
|
|
66
|
+
# ip_address: request.remote_ip,
|
|
67
|
+
# app_version: "1.2.3",
|
|
68
|
+
# metadata: { card_type: "visa", amount: 99.99 },
|
|
69
|
+
# severity: :high
|
|
70
|
+
# )
|
|
71
|
+
def self.report(
|
|
72
|
+
error_type:,
|
|
73
|
+
message:,
|
|
74
|
+
backtrace: nil,
|
|
75
|
+
platform: nil,
|
|
76
|
+
user_id: nil,
|
|
77
|
+
request_url: nil,
|
|
78
|
+
user_agent: nil,
|
|
79
|
+
ip_address: nil,
|
|
80
|
+
app_version: nil,
|
|
81
|
+
metadata: nil,
|
|
82
|
+
occurred_at: nil,
|
|
83
|
+
severity: nil,
|
|
84
|
+
source: nil
|
|
85
|
+
)
|
|
86
|
+
# Create a synthetic exception object that quacks like a Ruby exception
|
|
87
|
+
synthetic_exception = SyntheticException.new(
|
|
88
|
+
error_type: error_type,
|
|
89
|
+
message: message,
|
|
90
|
+
backtrace: normalize_backtrace(backtrace)
|
|
91
|
+
)
|
|
92
|
+
|
|
93
|
+
# Build context hash for LogError
|
|
94
|
+
context = {
|
|
95
|
+
source: source || "manual",
|
|
96
|
+
user_id: user_id,
|
|
97
|
+
request_url: request_url,
|
|
98
|
+
user_agent: user_agent,
|
|
99
|
+
ip_address: ip_address,
|
|
100
|
+
platform: platform,
|
|
101
|
+
app_version: app_version,
|
|
102
|
+
metadata: metadata,
|
|
103
|
+
occurred_at: occurred_at || Time.current,
|
|
104
|
+
severity: severity
|
|
105
|
+
}.compact # Remove nil values
|
|
106
|
+
|
|
107
|
+
# Use the existing LogError command
|
|
108
|
+
Commands::LogError.call(synthetic_exception, context)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Normalize backtrace to array of strings
|
|
112
|
+
# @param backtrace [Array<String>, String, nil]
|
|
113
|
+
# @return [Array<String>]
|
|
114
|
+
private_class_method def self.normalize_backtrace(backtrace)
|
|
115
|
+
return [] if backtrace.nil?
|
|
116
|
+
return backtrace if backtrace.is_a?(Array)
|
|
117
|
+
return backtrace.split("\n") if backtrace.is_a?(String)
|
|
118
|
+
[]
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# SyntheticException: A fake exception object for manual error reporting
|
|
122
|
+
#
|
|
123
|
+
# This class mimics a Ruby Exception to work with the existing LogError command,
|
|
124
|
+
# but represents errors from non-Ruby sources (frontend, mobile, etc.)
|
|
125
|
+
#
|
|
126
|
+
# @api private
|
|
127
|
+
class SyntheticException
|
|
128
|
+
attr_reader :message, :backtrace
|
|
129
|
+
|
|
130
|
+
# @param error_type [String] The error class name
|
|
131
|
+
# @param message [String] The error message
|
|
132
|
+
# @param backtrace [Array<String>] The stack trace
|
|
133
|
+
def initialize(error_type:, message:, backtrace:)
|
|
134
|
+
@error_type = error_type
|
|
135
|
+
@message = message
|
|
136
|
+
@backtrace = backtrace
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# Returns a mock class object that represents the error type
|
|
140
|
+
# @return [Object] A class-like object with the error type as its name
|
|
141
|
+
def class
|
|
142
|
+
# Return a simple object that quacks like a class
|
|
143
|
+
# This allows the error type to be stored correctly in the database
|
|
144
|
+
@class ||= MockClass.new(@error_type)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# MockClass: A simple class-like object for error typing
|
|
148
|
+
# @api private
|
|
149
|
+
class MockClass
|
|
150
|
+
def initialize(error_type)
|
|
151
|
+
@error_type = error_type
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def name
|
|
155
|
+
@error_type
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def to_s
|
|
159
|
+
@error_type
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Check if this is a specific error type
|
|
164
|
+
# @param klass [Class, String] The class to check against
|
|
165
|
+
# @return [Boolean]
|
|
166
|
+
def is_a?(klass)
|
|
167
|
+
return true if klass == self.class
|
|
168
|
+
return true if klass == SyntheticException
|
|
169
|
+
return true if klass.to_s == @error_type
|
|
170
|
+
false
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
# Inspect for debugging
|
|
174
|
+
# @return [String]
|
|
175
|
+
def inspect
|
|
176
|
+
"#<#{@error_type}: #{@message}>"
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
# Namespace for dynamically created manual error classes
|
|
181
|
+
# This keeps them separate from real Ruby exceptions
|
|
182
|
+
module ManualErrors
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
@@ -121,6 +121,9 @@ module RailsErrorDashboard
|
|
|
121
121
|
end
|
|
122
122
|
|
|
123
123
|
def detect_platform
|
|
124
|
+
# If platform is explicitly provided in context, use it
|
|
125
|
+
return @context[:platform] if @context[:platform].present?
|
|
126
|
+
|
|
124
127
|
# Check if it's from a mobile request
|
|
125
128
|
user_agent = extract_user_agent
|
|
126
129
|
|
|
@@ -2,6 +2,7 @@ require "rails_error_dashboard/version"
|
|
|
2
2
|
require "rails_error_dashboard/engine"
|
|
3
3
|
require "rails_error_dashboard/configuration"
|
|
4
4
|
require "rails_error_dashboard/logger"
|
|
5
|
+
require "rails_error_dashboard/manual_error_reporter"
|
|
5
6
|
|
|
6
7
|
# External dependencies
|
|
7
8
|
require "pagy"
|
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.1.
|
|
4
|
+
version: 0.1.20
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Anjan Jagirdar
|
|
@@ -342,6 +342,7 @@ files:
|
|
|
342
342
|
- lib/rails_error_dashboard/engine.rb
|
|
343
343
|
- lib/rails_error_dashboard/error_reporter.rb
|
|
344
344
|
- lib/rails_error_dashboard/logger.rb
|
|
345
|
+
- lib/rails_error_dashboard/manual_error_reporter.rb
|
|
345
346
|
- lib/rails_error_dashboard/middleware/error_catcher.rb
|
|
346
347
|
- lib/rails_error_dashboard/middleware/rate_limiter.rb
|
|
347
348
|
- lib/rails_error_dashboard/plugin.rb
|
|
@@ -379,7 +380,7 @@ metadata:
|
|
|
379
380
|
source_code_uri: https://github.com/AnjanJ/rails_error_dashboard
|
|
380
381
|
changelog_uri: https://github.com/AnjanJ/rails_error_dashboard/blob/main/CHANGELOG.md
|
|
381
382
|
post_install_message: "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n
|
|
382
|
-
\ Rails Error Dashboard v0.1.
|
|
383
|
+
\ Rails Error Dashboard v0.1.20\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n\n\U0001F195
|
|
383
384
|
First time? Quick start:\n rails generate rails_error_dashboard:install\n rails
|
|
384
385
|
db:migrate\n # Add to config/routes.rb:\n mount RailsErrorDashboard::Engine
|
|
385
386
|
=> '/error_dashboard'\n\n\U0001F504 Upgrading from v0.1.x?\n rails db:migrate\n
|