Skip to content

merge: resolve main into task/1_refactoring (error triple + analytics) - #4

Merged
pviti merged 5 commits into
task/1_refactoringfrom
task/1_refactoring-merged
Jul 31, 2026
Merged

merge: resolve main into task/1_refactoring (error triple + analytics)#4
pviti merged 5 commits into
task/1_refactoringfrom
task/1_refactoring-merged

Conversation

@pviti

@pviti pviti commented Jul 28, 2026

Copy link
Copy Markdown
Member

Targets task/1_refactoring, not main: merging this clears the conflicts on #2 without anyone force-pushing over your branch, and lets you see how each one was resolved before accepting it.

My fault that they exist — I merged #3 into main while your PR was open, without checking.

The five conflicts

The two changes are additive, not competing — nothing was dropped from either side.

File Kept from yours Kept from mine
api_error.rb grouped @!attribute docs, freeze code/title/detail, #hint
http_client.rb all of it (body moved to Request) — re-applied in request.rb, see below
client.rb bare requires, grouped docs, freeze analytics wired + documented
lib/rail0.rb $LOAD_PATH setup, require list error_hints before api_error
README.md Request/DefaultLogger structure lines api_error + error_hints descriptions

freeze still holds with the extra ivars — they are all assigned before it.

The one resolution that could have done damage is http_client.rb. Your refactoring moved the body into Request, so my edit had nowhere to live there; taking your file wholesale would have silently reverted it. The fix is re-applied in request.rb, which now also passes title: to ApiError:

body[:code] || body[:error] || body[:status]     # was: status first — the family, not the condition
body[:detail] || body[:message] || body[:error]  # was: detail ignored

Without that, e.error would report invalid_state where the gateway said amount_exceeds_refundable.

One fix of yours, found on the way

lib/rail0/default_logger.rb requires "logger", which nothing declares. It left Ruby's default gems in 4.0, so under bundler on a Ruby this gemspec claims to support (required_ruby_version ">= 3.0", no upper bound) requiring the SDK fails outright — that is what stopped me verifying the merge. Added as a runtime dependency in the gemspec; drop it if you would rather pin the Ruby version instead.

Verification

107 examples, 0 failures. Run on Ruby 4.0.5: rbsecp256k1 6.0.0 does not build against the 3.3.4 you pinned on this machine, so the suite has not been exercised on 3.3.4 here — worth a run on your side.

🤖 Generated with Claude Code

pviti and others added 5 commits July 28, 2026 15:41
…tics

This SDK had been parked while go and cli moved on, so it was three things behind.

ERRORS. The gateway answers every error with a code/title/detail triple, where `code` is
the specific condition and `detail` a sentence written to be shown to a user. ApiError
read `status` — the wider FAMILY — as the code, so a caller branching on it got
"invalid_state" where the gateway said "amount_exceeds_refundable", and printed what, for
state guards, used to be the bare code. It now prefers `code` (falling back to `error`
then `status`, so an older gateway still yields its most specific value) and carries
`title` and `detail`; `detail` is also the exception's message.

HINTS. Rail0.describe_error and ApiError#hint bring the SDK level with
rail0.DescribeError (go) and describeError (ts) — the same table, including the codes the
gateway learned to distinguish: token-level reverts (the most common failures in
practice, and none of them raised by RAIL0), broadcast rejections that used to arrive as
one opaque rpc_error, the three 403s that used to share "forbidden", and the
in-flight-version guards. Documented as a SUPPLEMENT to the gateway's detail, not a
replacement.

ANALYTICS. The one resource go and ts had and this did not — summary, timeseries,
breakdown, with the filters they share. Volume is only reported when a query pins both
token and chain_id, and the resource says why: amounts in different tokens are different
units, so a sum across them looks meaningful and isn't.

types.rb regenerated from the gateway schema (Error gains code/title/detail, Transaction
gains error_title/error_detail, Token gains active).

90 examples, 0 failures — 7 new, covering code-over-status precedence, the fallback to
the older field names, the bare-HTTP-status floor, and the hint table's coverage of the
two families a user cannot diagnose from the code alone.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
feat: align with the gateway — code/title/detail errors, hints, analytics
Resolves the five conflicts my error/analytics change (#3) created by landing in main
while this branch was open. My fault for merging without checking what was open.

Nothing was dropped on either side — the two changes are additive, not competing:

- api_error.rb — his grouped @!attribute docs and `freeze`, plus code/title/detail and
  #hint. Freezing still holds with the extra ivars, they are all set before it.
- http_client.rb — entirely his: the body moved to Request, so my edit had nowhere to
  live here. The fix was RE-APPLIED in request.rb, where those methods now are; taking
  "his" file wholesale would have silently reverted it, which is the one resolution that
  does damage: error_code would go back to reading `status` (the family) over `code` (the
  condition), and error_message would ignore `detail`. request.rb also now passes
  title: to ApiError.
- client.rb — his bare requires (his $LOAD_PATH additions make them work) and his
  grouped docs and freeze, with analytics wired in and documented alongside the rest.
- lib/rail0.rb — his $LOAD_PATH setup and require list, plus error_hints before
  api_error (ApiError#hint calls Rail0.describe_error).
- README.md — his Request/DefaultLogger structure lines, plus the api_error and
  error_hints descriptions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Found while trying to run this branch's suite: lib/rail0/default_logger.rb requires
"logger" at load time, but nothing declares it. `logger` left Ruby's default gems in
4.0, so under bundler on a Ruby this gemspec claims to support (required_ruby_version
">= 3.0", no upper bound) requiring the SDK fails outright:

  LoadError: cannot load such file -- logger
  ./lib/rail0/default_logger.rb:3

Declared as a runtime dependency rather than added to the Gemfile's development group,
because it is the library that needs it, not the tests. With it, the suite runs: 107
examples, 0 failures.

Included in this branch because without it the merge cannot be verified at all; drop it
if you would rather pin the Ruby version instead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Matches the cleanup this branch made repo-wide — no inline implementation comments, no
section dividers, class/module docs and YARD @param/@return kept — to the files that came
in from main, which still carried the gateway repo's heavier commenting style.

Dropped: the family dividers inside ERROR_HINTS, the rationale paragraphs on
ApiError/#hint and the analytics methods, the notes above request.rb's error_code and
error_message (this branch had already stripped the originals there), the require note in
lib/rail0.rb, and the gemspec paragraph — reduced to the one line that says why the
dependency exists.

Kept where it earns its place: what each class is for, and every @param/@return.

analytics.rb also picks up the conventions the other resources gained here — `require
"query"`, `attr_reader :http` with `freeze`, and calling `http` rather than `@http` — so
the new resource reads like its siblings rather than like an import.

The reasoning those comments carried is not lost: it is in PR #4's description, where the
one resolution that could silently revert the fix is spelled out.

107 examples, 0 failures.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@pviti

pviti commented Jul 28, 2026

Copy link
Copy Markdown
Member Author

Applied this branch's comment convention to the files that came in from main — they still carried the gateway repo's heavier commenting style, which read as an import rather than as part of this refactoring.

Dropped: the family dividers inside ERROR_HINTS, the rationale paragraphs on ApiError / #hint and the analytics methods, the notes above request.rb's error_code and error_message (this branch had already stripped the originals there), the require note in lib/rail0.rb, and the gemspec paragraph — reduced to the single line that says why the dependency exists.

Kept: what each class is for, and every @param / @return.

analytics.rb also picks up the conventions the other resources gained here — require "query", attr_reader :http with freeze, and calling http rather than @http — so the new resource reads like disputes.rb and payments.rb rather than like something bolted on.

Nothing explanatory was lost, only relocated: the one resolution that could silently revert the error fix (http_client.rbrequest.rb) is spelled out in the PR description above, which is where it survives a future refactoring better than a comment would.

107 examples, 0 failures.

@pviti
pviti requested a review from mkcosta July 28, 2026 14:35
@pviti
pviti merged commit 843951b into task/1_refactoring Jul 31, 2026
@pviti
pviti deleted the task/1_refactoring-merged branch July 31, 2026 13:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant