activerabbit-ai 0.4.5 → 0.4.7

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: e2afb9bf892d3e3a7e83a65e224c791855aa7d6e86feb476ee0f66c108f617cd
4
- data.tar.gz: 20e74e7fa56e865bd707ccd852e62894fa73fc1d5ac2145d7d6a606dff351722
3
+ metadata.gz: 06e58258544f159566a756467253a1a2a6a0a696479b37cd1f265902928a3f8c
4
+ data.tar.gz: e12b3dcd16a43ca524027e2b0ecd608d8bbe0441f2f89586d7bb5d1f57dbda1a
5
5
  SHA512:
6
- metadata.gz: 40e742a6578a155441efe51fd97de272e8bfc7fe2e024cc2abe17e29ac2ee664079c6eb3093ae0aa311dea8f5438c96b60d88ba0a50e2477fdc2cc01b7b32006
7
- data.tar.gz: 55fe08ec494af877576561418a7d3c9b63fd0b0bd34d3c04c3e59d5cb39d3d032992369ac056dc6e2417e75bad363fb5ac1dce115d3150765be7870b7859c34b
6
+ metadata.gz: eb2e853ad6f3791c567a9498af2a6684756042d0b7fa626e94ae057910422a594f0d705f5fbc923334af52c110062701db37c86766d14be17ef41d495e758fae
7
+ data.tar.gz: d498e0a7c16cb8abeb8c96724caf88ad32ac598e0d84994c90712de3e8f182a763aaeda73f39c8a3f94b00c31ff1b5b3629535946313a8adec952ccb0bf0466b
data/CHANGELOG.md CHANGED
@@ -2,6 +2,35 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.4.7] - 2025-11-06
6
+
7
+ ### Fixed
8
+ - **Multiple duplicate events**: Disabled Rails Error Reporter and rack.exception fallback subscriptions
9
+ - These mechanisms were creating 3-4 duplicate events for each error
10
+ - Middleware is now the single source of truth for error capture, providing the best context
11
+ - Each error now creates exactly ONE event instead of 3-4
12
+
13
+ ### Changed
14
+ - Rails Error Reporter subscription: DISABLED (middleware captures all controller errors)
15
+ - rack.exception subscription: DISABLED (middleware captures all rack-level errors)
16
+ - Middleware remains as the primary and only error capture mechanism
17
+
18
+ ## [0.4.6] - 2025-11-05
19
+
20
+ ### Fixed
21
+ - **Duplicate issues bug**: Fixed error reporting creating duplicate issues with "unknown" controller_action
22
+ - Error Reporter now properly extracts controller/action from Rails routing context
23
+ - `rack.exception` fallback now also extracts controller_action correctly
24
+ - All error capture mechanisms now produce consistent controller_action values, preventing duplicate issue grouping
25
+
26
+ ### Details
27
+ Previously, the same error could create multiple issues in the dashboard:
28
+ - Middleware capture: `TestController#action` ✓
29
+ - Rails Error Reporter: `unknown` ✗ (created duplicate)
30
+ - Rack.exception fallback: `unknown` ✗ (created duplicate)
31
+
32
+ Now all mechanisms extract and use the same controller_action format, ensuring errors are properly grouped into a single issue.
33
+
5
34
  ## [0.4.4] - 2025-10-22
6
35
 
7
36
  ### Improved
Binary file
@@ -56,6 +56,20 @@ module ActiveRabbit
56
56
  # Top-level convenience for UI
57
57
  ctx[:request_path] = ctx[:request][:path]
58
58
  ctx[:request_method] = ctx[:request][:method]
59
+
60
+ # Extract controller_action from routing info to prevent duplicate issues
61
+ routing = req_info[:routing]
62
+ if routing && routing[:controller] && routing[:action]
63
+ controller_name = routing[:controller].to_s
64
+ action_name = routing[:action].to_s
65
+ ctx[:controller_action] = "#{controller_name}##{action_name}"
66
+ end
67
+ else
68
+ # Fallback: Try to extract from controller instance in context
69
+ controller = context && (context[:controller] || context['controller'])
70
+ if controller && controller.respond_to?(:controller_name) && controller.respond_to?(:action_name)
71
+ ctx[:controller_action] = "#{controller.controller_name.camelize}Controller##{controller.action_name}"
72
+ end
59
73
  end
60
74
 
61
75
  if defined?(ActionController::RoutingError) && exception.is_a?(ActionController::RoutingError)
@@ -77,10 +77,22 @@ module ActiveRabbit
77
77
  private
78
78
 
79
79
  def build_performance_data(name:, duration_ms:, metadata:)
80
+ metadata = metadata || {}
81
+
82
+ # Extract important fields from metadata for top-level inclusion
83
+ controller = metadata[:controller] || metadata["controller"]
84
+ action = metadata[:action] || metadata["action"]
85
+ controller_action = "#{controller}##{action}" if controller && action
86
+
80
87
  data = {
81
88
  name: name.to_s,
82
89
  duration_ms: duration_ms.to_f,
83
- metadata: scrub_pii(metadata || {}),
90
+ db_duration_ms: metadata[:db_runtime] || metadata["db_runtime"],
91
+ view_duration_ms: metadata[:view_runtime] || metadata["view_runtime"],
92
+ controller_action: controller_action,
93
+ request_path: metadata[:path] || metadata["path"],
94
+ request_method: metadata[:method] || metadata["method"],
95
+ metadata: scrub_pii(metadata),
84
96
  timestamp: Time.now.iso8601(3),
85
97
  environment: configuration.environment,
86
98
  release: configuration.release,
@@ -59,25 +59,26 @@ module ActiveRabbit
59
59
  # Defer complex subscriptions until after initialization
60
60
  app.config.after_initialize do
61
61
 
62
- # Fallback: low-level rack.exception subscription (older Rails and deep middleware errors)
63
- ActiveSupport::Notifications.subscribe("rack.exception") do |*args|
64
- begin
65
- payload = args.last
66
- exception = payload[:exception_object]
67
- env = payload[:env]
68
- next unless exception
69
-
70
- ActiveRabbit::Reporting.report_exception(
71
- exception,
72
- env: env,
73
- handled: false,
74
- source: "rack.exception",
75
- force: true
76
- )
77
- rescue => e
78
- Rails.logger.error "[ActiveRabbit] Error handling rack.exception: #{e.class}: #{e.message}" if defined?(Rails)
79
- end
80
- end
62
+ # DISABLED: rack.exception creates duplicate events because middleware already catches all errors
63
+ # The middleware is the primary error capture mechanism and catches errors at the optimal level
64
+ # ActiveSupport::Notifications.subscribe("rack.exception") do |*args|
65
+ # begin
66
+ # payload = args.last
67
+ # exception = payload[:exception_object]
68
+ # env = payload[:env]
69
+ # next unless exception
70
+ #
71
+ # ActiveRabbit::Reporting.report_exception(
72
+ # exception,
73
+ # env: env,
74
+ # handled: false,
75
+ # source: "rack.exception",
76
+ # force: true
77
+ # )
78
+ # rescue => e
79
+ # Rails.logger.error "[ActiveRabbit] Error handling rack.exception: #{e.class}: #{e.message}" if defined?(Rails)
80
+ # end
81
+ # end
81
82
  end
82
83
  end
83
84
 
@@ -287,10 +288,11 @@ module ActiveRabbit
287
288
  end
288
289
 
289
290
  initializer "active_rabbit.error_reporter" do |app|
290
- # Defer attaching so application config has been applied
291
- app.config.after_initialize do
292
- ActiveRabbit::Client::ErrorReporter.attach!
293
- end
291
+ # DISABLED: Rails error reporter creates duplicate events because middleware already catches all errors
292
+ # The middleware provides better context and catches errors at the right level
293
+ # app.config.after_initialize do
294
+ # ActiveRabbit::Client::ErrorReporter.attach!
295
+ # end
294
296
  end
295
297
 
296
298
  initializer "active_rabbit.sidekiq" do
@@ -402,6 +404,7 @@ module ActiveRabbit
402
404
  duration_ms = ((finished - started) * 1000).round(2)
403
405
 
404
406
  Rails.logger.info "[ActiveRabbit] 📊 Controller action: #{payload[:controller]}##{payload[:action]} - #{duration_ms}ms"
407
+ Rails.logger.info "[ActiveRabbit] 📊 DB runtime: #{payload[:db_runtime]}, View runtime: #{payload[:view_runtime]}"
405
408
 
406
409
  ActiveRabbit::Client.track_performance(
407
410
  "controller.action",
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveRabbit
4
4
  module Client
5
- VERSION = "0.4.5"
5
+ VERSION = "0.4.7"
6
6
  end
7
7
  end
@@ -16,6 +16,14 @@ module ActiveRabbit
16
16
  enriched_context[:source] ||= source
17
17
  enriched_context[:handled] = handled if !enriched_context.key?(:handled)
18
18
 
19
+ # Extract controller_action from routing info to prevent duplicate issues
20
+ routing = req_info[:routing]
21
+ if routing && routing[:controller] && routing[:action] && !enriched_context[:controller_action]
22
+ controller_name = routing[:controller].to_s
23
+ action_name = routing[:action].to_s
24
+ enriched_context[:controller_action] = "#{controller_name}##{action_name}"
25
+ end
26
+
19
27
  # Enrich for routing errors so UI shows controller action and 404 specifics
20
28
  if defined?(ActionController::RoutingError) && exception.is_a?(ActionController::RoutingError)
21
29
  enriched_context[:controller_action] ||= 'Routing#not_found'
data/lib/active_rabbit.rb CHANGED
@@ -4,11 +4,4 @@ require_relative "active_rabbit/client"
4
4
  require_relative "active_rabbit/routing/not_found_app"
5
5
 
6
6
  # Load Rails integration
7
- if defined?(Rails)
8
- begin
9
- require_relative "active_rabbit/client/railtie"
10
- rescue => e
11
- warn "[ActiveRabbit] Rails integration failed: #{e.message}" if Rails.env&.development?
12
- warn "[ActiveRabbit] Backtrace: #{e.backtrace.first(5).join(', ')}" if Rails.env&.development?
13
- end
14
- end
7
+ require_relative "active_rabbit/client/railtie" if defined?(Rails)
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Compatibility loader for Bundler and Rails autoloading
4
+ # because gem names cannot map "-" to "_" automatically.
5
+ # This ensures `require "activerabbit-ai"` loads the real code.
6
+
7
+ require_relative "active_rabbit"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerabbit-ai
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.5
4
+ version: 0.4.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alex Shapalov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-10-25 00:00:00.000000000 Z
11
+ date: 2025-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -81,6 +81,7 @@ files:
81
81
  - README.md
82
82
  - Rakefile
83
83
  - TESTING_GUIDE.md
84
+ - activerabbit-ai-0.4.5.gem
84
85
  - check_api_data.rb
85
86
  - examples/rails_app_testing.rb
86
87
  - examples/rails_integration.rb
@@ -105,6 +106,7 @@ files:
105
106
  - lib/active_rabbit/middleware/error_capture_middleware.rb
106
107
  - lib/active_rabbit/reporting.rb
107
108
  - lib/active_rabbit/routing/not_found_app.rb
109
+ - lib/activerabbit-ai.rb
108
110
  - script/test_production_readiness.rb
109
111
  - script/test_rails_integration.rb
110
112
  - setup_local_gem_testing.sh