rails-informant 0.4.3 → 0.4.5
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/README.md +19 -0
- data/lib/rails_informant/mcp/tools/verify_pending_fixes.rb +47 -3
- data/lib/rails_informant.rb +6 -14
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 6d0af47e9b626dfed7bcf7a29cb9817ff2fd41ada4700a61a0fab3579c863742
|
|
4
|
+
data.tar.gz: e130792dad9233646126fed6bcac17c339e50f5aeb566710307661078a0f7772
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ab3256ce6ae5de9d3356346d9e5b4c0988f5170439b54a77945051980164a67e2c9e37a6ced0de22e7e68271ac3b5053a1292f4de8cc9f8c5c895e1aad651d0c
|
|
7
|
+
data.tar.gz: 46530d277944774af55b2b0012d45a76e471c690d35e5324385ade0a2c9cc67704dfcbf0aa545c4172dba8c75f031d00ee591478b8fd6cb2669a54ddeed42295
|
data/README.md
CHANGED
|
@@ -100,6 +100,25 @@ Every option can be set via an environment variable. The initializer takes prece
|
|
|
100
100
|
|
|
101
101
|
## Noise Suppression
|
|
102
102
|
|
|
103
|
+
### Default Ignored Exceptions
|
|
104
|
+
|
|
105
|
+
Informant ignores only exceptions that are noise in **every** context: `SignalException`
|
|
106
|
+
and `SystemExit` (process control), plus a few client/tamper errors
|
|
107
|
+
(`Rack::Utils::InvalidParameterError`, `Mime::Type::InvalidMimeType`,
|
|
108
|
+
`CGI::Session::CookieStore::TamperedWithCookie`).
|
|
109
|
+
|
|
110
|
+
It deliberately does **not** ignore Rails' HTTP client errors -- `RecordNotFound`,
|
|
111
|
+
`RoutingError`, `ParameterMissing`, and the rest of the 4xx family. On the request path
|
|
112
|
+
Rails already maps those to responses (404, 422, ...) and never reports them to
|
|
113
|
+
`Rails.error`, so suppressing them again here was redundant. Off the request path -- in a
|
|
114
|
+
**background job**, a rake task, or wrapped as the cause of another error -- those same
|
|
115
|
+
exceptions are real bugs, so Informant records them. A job that dies on an
|
|
116
|
+
`ActiveJob::DeserializationError` caused by a missing record now alerts instead of
|
|
117
|
+
vanishing silently.
|
|
118
|
+
|
|
119
|
+
Add your own classes with `config.ignored_exceptions`; it still walks the cause chain, so
|
|
120
|
+
ignoring a class also ignores exceptions that wrap it.
|
|
121
|
+
|
|
103
122
|
### Silenced Blocks
|
|
104
123
|
|
|
105
124
|
```ruby
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
require "json"
|
|
2
|
+
require "open3"
|
|
3
|
+
|
|
1
4
|
module RailsInformant
|
|
2
5
|
module Mcp
|
|
3
6
|
module Tools
|
|
4
7
|
class VerifyPendingFixes < BaseTool
|
|
5
8
|
tool_name "verify_pending_fixes"
|
|
6
|
-
description "Verify fix_pending errors by checking
|
|
9
|
+
description "Verify fix_pending errors by checking whether the fix is in the deployed code: first by fix_sha ancestry, then — for squash/rebase merges, where fix_sha is not an ancestor of the deploy — by the fix PR's merge commit. Resolves verified fixes. Requires git locally (and gh for the PR fallback). Results reflect local git state — run git fetch first to ensure accuracy."
|
|
7
10
|
input_schema(
|
|
8
11
|
properties: {
|
|
9
12
|
auto_resolve: { type: "boolean", description: "Resolve verified fixes automatically (default: true)" },
|
|
@@ -31,8 +34,7 @@ module RailsInformant
|
|
|
31
34
|
pending = []
|
|
32
35
|
|
|
33
36
|
errors.each do |error|
|
|
34
|
-
|
|
35
|
-
if fix_sha && ancestor?(fix_sha, ref)
|
|
37
|
+
if verified?(error, ref)
|
|
36
38
|
verified << error
|
|
37
39
|
else
|
|
38
40
|
pending << error
|
|
@@ -55,10 +57,52 @@ module RailsInformant
|
|
|
55
57
|
|
|
56
58
|
private
|
|
57
59
|
|
|
60
|
+
def verified?(error, target_ref)
|
|
61
|
+
fix_sha = error["fix_sha"]
|
|
62
|
+
return true if fix_sha && ancestor?(fix_sha, target_ref)
|
|
63
|
+
|
|
64
|
+
# Squash and rebase merges create a new commit unrelated to fix_sha, so the
|
|
65
|
+
# recorded SHA is never an ancestor of the deploy. Fall back to the PR's merge
|
|
66
|
+
# commit, which is in the deployed history regardless of merge strategy.
|
|
67
|
+
merge_sha = merged_pr_commit error["fix_pr_url"]
|
|
68
|
+
!merge_sha.nil? && ancestor?(merge_sha, target_ref)
|
|
69
|
+
end
|
|
70
|
+
|
|
58
71
|
def ancestor?(fix_sha, target_ref)
|
|
59
72
|
system "git", "merge-base", "--is-ancestor", fix_sha, target_ref, out: File::NULL, err: File::NULL
|
|
60
73
|
end
|
|
61
74
|
|
|
75
|
+
# Returns the merge commit SHA of a merged PR, or nil if the PR is unmerged, the
|
|
76
|
+
# URL is blank, or gh is unavailable. Best-effort fetches the commit so the
|
|
77
|
+
# subsequent ancestry check can see it. Uses the array form (no shell) so the
|
|
78
|
+
# PR URL can't be interpreted as a command.
|
|
79
|
+
def merged_pr_commit(pr_url)
|
|
80
|
+
return if pr_url.nil? || pr_url.empty?
|
|
81
|
+
return unless gh_available?
|
|
82
|
+
|
|
83
|
+
output, status = Open3.capture2 "gh", "pr", "view", pr_url, "--json", "state,mergeCommit", err: File::NULL
|
|
84
|
+
return unless status.success? && !output.strip.empty?
|
|
85
|
+
|
|
86
|
+
data = JSON.parse output
|
|
87
|
+
return unless data["state"] == "MERGED"
|
|
88
|
+
|
|
89
|
+
merge_sha = data.dig "mergeCommit", "oid"
|
|
90
|
+
return if merge_sha.nil? || merge_sha.empty?
|
|
91
|
+
|
|
92
|
+
fetch_commit merge_sha
|
|
93
|
+
merge_sha
|
|
94
|
+
rescue JSON::ParserError
|
|
95
|
+
nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def fetch_commit(sha)
|
|
99
|
+
system "git", "fetch", "--quiet", "origin", sha, out: File::NULL, err: File::NULL
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def gh_available?
|
|
103
|
+
system "gh", "--version", out: File::NULL, err: File::NULL
|
|
104
|
+
end
|
|
105
|
+
|
|
62
106
|
def fetch_all_fix_pending(client)
|
|
63
107
|
errors = []
|
|
64
108
|
page = 1
|
data/lib/rails_informant.rb
CHANGED
|
@@ -5,25 +5,17 @@ module RailsInformant
|
|
|
5
5
|
InvalidParameterError = Class.new(StandardError)
|
|
6
6
|
NotifierError = Class.new(StandardError)
|
|
7
7
|
|
|
8
|
+
# Only exceptions that are noise in *every* context. Rails 8.1 maps HTTP
|
|
9
|
+
# client errors (404s, routing, bad params) via rescue_responses and never
|
|
10
|
+
# reports them to Rails.error on the request path, so listing them here was
|
|
11
|
+
# redundant for requests and wrongly suppressed the same exceptions when they
|
|
12
|
+
# are real bugs in background jobs (e.g. a job's RecordNotFound). Those are
|
|
13
|
+
# recorded now; what remains is process-control and client/tamper noise.
|
|
8
14
|
IGNORED_EXCEPTIONS_DEFAULT = %w[
|
|
9
|
-
AbstractController::ActionNotFound
|
|
10
|
-
ActionController::BadRequest
|
|
11
|
-
ActionController::InvalidAuthenticityToken
|
|
12
|
-
ActionController::InvalidCrossOriginRequest
|
|
13
|
-
ActionController::MethodNotAllowed
|
|
14
|
-
ActionController::NotImplemented
|
|
15
|
-
ActionController::ParameterMissing
|
|
16
|
-
ActionController::RoutingError
|
|
17
15
|
ActionController::UnknownAction
|
|
18
|
-
ActionController::UnknownFormat
|
|
19
|
-
ActionController::UnknownHttpMethod
|
|
20
16
|
ActionController::UrlGenerationError
|
|
21
|
-
ActionDispatch::Http::MimeNegotiation::InvalidType
|
|
22
|
-
ActiveRecord::RecordNotFound
|
|
23
17
|
CGI::Session::CookieStore::TamperedWithCookie
|
|
24
18
|
Mime::Type::InvalidMimeType
|
|
25
|
-
Rack::QueryParser::InvalidParameterError
|
|
26
|
-
Rack::QueryParser::ParameterTypeError
|
|
27
19
|
Rack::Utils::InvalidParameterError
|
|
28
20
|
SignalException
|
|
29
21
|
SystemExit
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rails-informant
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.4.
|
|
4
|
+
version: 0.4.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Daniel López Prat
|
|
@@ -195,7 +195,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
195
195
|
- !ruby/object:Gem::Version
|
|
196
196
|
version: '0'
|
|
197
197
|
requirements: []
|
|
198
|
-
rubygems_version: 4.0.
|
|
198
|
+
rubygems_version: 4.0.10
|
|
199
199
|
specification_version: 4
|
|
200
200
|
summary: Self-hosted error monitoring for Rails with MCP server for agentic workflows
|
|
201
201
|
test_files: []
|