bug_courier 1.0.0 → 1.1.1

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: 36cb1c6c27aafcb8c121c7c45abd1096704ba4f2c93dac261cfc65edac80cf48
4
- data.tar.gz: 6331194fdee5a7140ab0bc951efe0d4a18d16415813275a0991b58fe30aaa2d0
3
+ metadata.gz: b6b455974d2717751253d5102bf28f36bb04a4ec924f318904ab6341ab1b11c1
4
+ data.tar.gz: '047847d8a4b32ec1c6777a5640d135b722118175258c8124096166d8b939a671'
5
5
  SHA512:
6
- metadata.gz: cdb705a50f9c96731d8acf9f2c0960ad5bedc34a477e452b3e68895db8f22ca5001f91d461546e03eeafcae6957729dfc41b284442825cada9e7df093ed8d2bf
7
- data.tar.gz: 1c185ff6306357c3b1cec72dff37018c97cf42c0c8b1054da8683fc52c5a242c5afd9f80a3bf9809e3ec587fe01df0a85a63b59bd12daf27f52ee3d2cb7601c4
6
+ metadata.gz: 8331b81d74c0b238d7fdaf51f1c7fc8b1ef896677a4ac93456e1334d803a2f886a383f30ebd5205d743a9c4739400a9041f42ac165a9943701966682455950ef
7
+ data.tar.gz: 17b29320dcd0919006c8b8db017eece9ade5298191ae6e96ec8f5e840d5c44038bdf222a797b0b8e7b0d6c676ae1cde0e8a2b8779d824bf0d1c940aa1bc42e47
data/CHANGELOG.md ADDED
@@ -0,0 +1,59 @@
1
+ # Changelog
2
+
3
+ All notable changes to BugCourier are documented in this file.
4
+
5
+ ## [v1.1.1](https://github.com/sgnh/bug-courier/compare/v1.1.0...v1.1.1) — 2026-03-11
6
+
7
+ ### Fixed
8
+
9
+ - Middleware now rescues only `StandardError`, avoiding interception of fatal Ruby exceptions such as `SystemExit` and `SignalException`
10
+ - `GithubClient` now handles transport failures that return no HTTP response without raising secondary `NoMethodError` exceptions
11
+
12
+ ## [v1.1.0](https://github.com/sgnh/bug-courier/compare/v1.0.0...v1.1.0) — 2026-03-11
13
+
14
+ ### Added
15
+
16
+ - `ignore_exceptions` configuration option to skip reporting for specific exception classes (e.g., `ActiveRecord::RecordNotFound`, `ActionController::RoutingError`)
17
+ - Supports both class constants and string class names in the ignore list
18
+ - Install generator now includes commented-out `ignore_exceptions` example in the initializer
19
+
20
+ ### Changed
21
+
22
+ - `ExceptionHandler#handle` checks ignored exceptions before processing
23
+
24
+ ## [v1.0.0](https://github.com/sgnh/bug-courier/compare/v0.1.2...v1.0.0) — 2026-03-10
25
+
26
+ ### Changed
27
+
28
+ - Bumped to first stable release (1.0.0)
29
+
30
+ ### Documentation
31
+
32
+ - Added GitHub Copilot integration section to README explaining automatic issue creation and pull request workflows
33
+
34
+ ## [v0.1.2](https://github.com/sgnh/bug-courier/compare/v0.1.1...v0.1.2) — 2026-03-10
35
+
36
+ ### Fixed
37
+
38
+ - Changed middleware insertion order from `insert_before(0, ...)` to `insert_after(ActionDispatch::DebugExceptions, ...)` to ensure proper functionality within the Rails middleware stack
39
+
40
+ ## [v0.1.1](https://github.com/sgnh/bug-courier/compare/v0.1.0...v0.1.1) — 2026-03-10
41
+
42
+ ### Changed
43
+
44
+ - Lowered required Ruby version from `>= 3.2.0` to `>= 2.7.0`
45
+ - Lowered `railties` dependency from `>= 7.0` to `>= 6.1` for broader Rails compatibility
46
+
47
+ ## [v0.1.0] — 2026-03-10
48
+
49
+ ### Added
50
+
51
+ - Initial open source release
52
+ - Rack middleware to catch uncaught exceptions automatically
53
+ - `ExceptionHandler` with full error details, backtraces, and request context
54
+ - `GithubClient` for creating GitHub issues via the API
55
+ - Deduplication support to avoid duplicate issues (comments on existing ones instead)
56
+ - Rate limiting (default: 10 issues per hour)
57
+ - Configurable labels, assignees, and optional callback after issue creation
58
+ - Rails generator (`rails generate bug_courier:install`) to scaffold an initializer
59
+ - Railtie for automatic middleware integration in Rails apps
data/README.md CHANGED
@@ -70,8 +70,8 @@ Create a [GitHub personal access token](https://github.com/settings/tokens) with
70
70
 
71
71
  ## How It Works
72
72
 
73
- 1. BugCourier inserts a Rack middleware at the top of your middleware stack
74
- 2. When an uncaught exception propagates up, the middleware catches it, reports it asynchronously, then re-raises it so normal error handling continues
73
+ 1. BugCourier inserts a Rack middleware after `ActionDispatch::DebugExceptions` in the Rails middleware stack
74
+ 2. When a `StandardError` propagates up to that layer, the middleware reports it asynchronously, then re-raises it so normal error handling continues
75
75
  3. If deduplication is enabled, it searches for an existing open issue with the same title and adds a comment instead of creating a duplicate
76
76
  4. Rate limiting prevents flooding your repository with issues during error spikes
77
77
 
@@ -3,7 +3,7 @@
3
3
  module BugCourier
4
4
  class Configuration
5
5
  attr_accessor :access_token, :repo, :labels, :assignees, :enabled,
6
- :deduplicate, :rate_limit, :callback
6
+ :deduplicate, :rate_limit, :callback, :ignore_exceptions
7
7
 
8
8
  def initialize
9
9
  @access_token = nil
@@ -14,6 +14,7 @@ module BugCourier
14
14
  @deduplicate = true
15
15
  @rate_limit = 10 # max issues per hour
16
16
  @callback = nil
17
+ @ignore_exceptions = []
17
18
  end
18
19
 
19
20
  def valid?
@@ -30,6 +30,7 @@ module BugCourier
30
30
  def handle(exception, env = {})
31
31
  return unless BugCourier.configuration.enabled
32
32
  return unless BugCourier.configuration.valid?
33
+ return if ignored?(exception)
33
34
  return unless @rate_limiter.allow?
34
35
 
35
36
  title = build_title(exception)
@@ -137,5 +138,14 @@ module BugCourier
137
138
 
138
139
  params.except("controller", "action").to_s.slice(0, 500)
139
140
  end
141
+
142
+ def ignored?(exception)
143
+ BugCourier.configuration.ignore_exceptions.any? do |klass|
144
+ klass = Object.const_get(klass) if klass.is_a?(String)
145
+ exception.is_a?(klass)
146
+ rescue NameError
147
+ false
148
+ end
149
+ end
140
150
  end
141
151
  end
@@ -26,7 +26,7 @@ module BugCourier
26
26
  response = post(uri, payload)
27
27
 
28
28
  unless response.is_a?(Net::HTTPCreated)
29
- BugCourier.logger&.error("[BugCourier] Failed to create GitHub issue: #{response.code} #{response.body}")
29
+ log_failure("Failed to create GitHub issue", response)
30
30
  return nil
31
31
  end
32
32
 
@@ -41,7 +41,7 @@ module BugCourier
41
41
  response = get(uri)
42
42
 
43
43
  unless response.is_a?(Net::HTTPOK)
44
- BugCourier.logger&.error("[BugCourier] Failed to search GitHub issues: #{response.code} #{response.body}")
44
+ log_failure("Failed to search GitHub issues", response)
45
45
  return nil
46
46
  end
47
47
 
@@ -56,7 +56,7 @@ module BugCourier
56
56
  response = post(uri, { body: body })
57
57
 
58
58
  unless response.is_a?(Net::HTTPCreated)
59
- BugCourier.logger&.error("[BugCourier] Failed to add comment to issue ##{issue_number}: #{response.code} #{response.body}")
59
+ log_failure("Failed to add comment to issue ##{issue_number}", response)
60
60
  return nil
61
61
  end
62
62
 
@@ -95,5 +95,15 @@ module BugCourier
95
95
  BugCourier.logger&.error("[BugCourier] HTTP request failed: #{e.message}")
96
96
  nil
97
97
  end
98
+
99
+ def log_failure(message, response)
100
+ details = if response.nil?
101
+ "no response received"
102
+ else
103
+ "#{response.code} #{response.body}"
104
+ end
105
+
106
+ BugCourier.logger&.error("[BugCourier] #{message}: #{details}")
107
+ end
98
108
  end
99
109
  end
@@ -9,7 +9,7 @@ module BugCourier
9
9
 
10
10
  def call(env)
11
11
  @app.call(env)
12
- rescue Exception => exception # rubocop:disable Lint/RescueException
12
+ rescue StandardError => exception
13
13
  @handler.handle(exception, env)
14
14
  raise
15
15
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module BugCourier
4
- VERSION = "1.0.0"
4
+ VERSION = "1.1.1"
5
5
  end
@@ -34,6 +34,12 @@ module BugCourier
34
34
  # Maximum number of issues to create per hour (default: 10)
35
35
  # config.rate_limit = 10
36
36
 
37
+ # Exception classes to ignore — these will not be reported (default: [])
38
+ # config.ignore_exceptions = [
39
+ # ActiveRecord::RecordNotFound,
40
+ # ActionController::RoutingError,
41
+ # ]
42
+
37
43
  # Optional callback — called after issue creation or commenting
38
44
  # config.callback = ->(action, issue) {
39
45
  # Rails.logger.info("[BugCourier] \#{action}: \#{issue['html_url']}")
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bug_courier
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Steffen Hansen
@@ -46,6 +46,7 @@ executables: []
46
46
  extensions: []
47
47
  extra_rdoc_files: []
48
48
  files:
49
+ - CHANGELOG.md
49
50
  - LICENSE.txt
50
51
  - README.md
51
52
  - Rakefile