Skip to content

🥅 server: skip retries for replay reverts#758

Merged
cruzdanilo merged 1 commit intomainfrom
replay
Feb 11, 2026
Merged

🥅 server: skip retries for replay reverts#758
cruzdanilo merged 1 commit intomainfrom
replay

Conversation

@nfmelendez
Copy link
Contributor

@nfmelendez nfmelendez commented Feb 11, 2026

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of replay reverts to skip retries and avoid unnecessary fatal error escalation, resulting in faster, more resilient transaction handling.
  • Tests

    • Added end-to-end tests covering replay scenarios across card creation, reversal, and refund-related flows to ensure consistent replay behavior.

Open with Devin

@changeset-bot
Copy link

changeset-bot bot commented Feb 11, 2026

🦋 Changeset detected

Latest commit: 03fdfa3

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@exactly/server Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

Walkthrough

Adds a changeset and implements Replay-specific short-circuit handling in panda server hooks: Replay revert errors are detected in multiple catch blocks, the active tracing span is marked, and the handler returns success to skip retry logic; tests for these replay scenarios are added.

Changes

Cohort / File(s) Summary
Changeset
.changeset/silent-streets-jump.md
New changeset file declaring a patch release for @exactly/server documenting "skip retries for replay reverts".
Server Hook Error Handling
server/hooks/panda.ts
Adds Replay-specific checks in three catch blocks: detect BaseError with a ContractFunctionRevertedError cause where data.errorName === "Replay", set panda.replay on the active tracing span (and related span attrs), and return { code: "ok" } to bypass fatal handling and retry logic.
Hook Tests
server/test/hooks/panda.test.ts
Adds three tests exercising card creation, reversal, and refund/reversal replay flows; each verifies a replayed request returns 200 on second attempt and that a single Replay fingerprint is captured.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Client as Client
participant Server as Server (panda hook)
participant Chain as Blockchain / Contract
participant Tracer as Tracing/Sentry

Client->>Server: POST transaction payload
Server->>Chain: submit/execute tx
Chain-->>Server: Contract revert (Replay)
alt Replay revert detected
Server->>Tracer: mark span (panda.replay / panda.transaction)
Server-->>Client: 200 / { code: "ok" } (short-circuit)
Server->>Tracer: capture Replay fingerprint
else Other error
Server->>Tracer: capture fatal error
Server-->>Client: error response (retry/fatal)
end

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: adding logic to skip retries for Replay errors by returning early from error handling. It is specific, concise, and directly relates to the primary objective of the changeset.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch replay

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello @nfmelendez, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request enhances the server's robustness by intelligently handling 'Replay' errors that can occur during contract interactions. By specifically identifying and acknowledging these errors with an 'ok' response, the system avoids redundant retries and reduces noise in error monitoring, leading to more efficient and stable operation. The changes also improve observability by adding relevant tracing attributes for these specific error scenarios.

Highlights

  • Replay Error Handling: Implemented specific error handling for ContractFunctionRevertedError instances where the errorName is 'Replay' within the panda.ts hook.
  • Retry Prevention: Ensured that when a 'Replay' error occurs, the server immediately returns an 'ok' response, effectively preventing unnecessary retries for these known idempotent operations.
  • Observability: Added OpenTelemetry attributes (panda.replay and panda.transaction) to the active span when a 'Replay' error is detected, improving tracing and debugging capabilities.
  • Test Coverage: Introduced new test cases to validate the correct behavior of the system when encountering 'Replay' errors during both initial transaction collection and subsequent reversals.
Changelog
  • .changeset/silent-streets-jump.md
    • Added a new changeset file to document the patch for skipping retries on replay reverts for the @exactly/server package.
  • server/hooks/panda.ts
    • Modified the post handler to include a new catch block that specifically checks for BaseError with a ContractFunctionRevertedError cause where errorName is 'Replay'.
    • Configured the handler to return an 'ok' JSON response immediately upon detecting a 'Replay' error.
    • Added panda.replay and panda.transaction attributes to the active OpenTelemetry span when a 'Replay' error is handled.
  • server/test/hooks/panda.test.ts
    • Added a new test case returns ok on replay to verify that the server correctly responds with 'ok' when a 'Replay' error occurs during a transaction collection.
    • Added another new test case returns ok on reversal replay to confirm the same 'ok' response for 'Replay' errors encountered during transaction reversals.
    • Included assertions to ensure captureException is called with appropriate details for 'Replay' errors in the new tests.
Activity
  • No specific activity (comments, reviews, progress) was provided in the context for this pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request correctly handles Replay errors from contract interactions by returning a 200 OK status, preventing webhook retries for both collection and refund flows. The changes are well-tested. While there is some duplicated error-handling logic, we will defer abstraction for now to avoid premature optimization, as per repository guidelines. A security audit has commenced, with the scope defined and SAST Reconnaissance tasks identified for the relevant files.

@cruzdanilo
Copy link
Member

@coderabbitai review

@cruzdanilo
Copy link
Member

@cursor review

@coderabbitai
Copy link

coderabbitai bot commented Feb 11, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@server/hooks/panda.ts`:
- Around line 732-739: Extract a small predicate function (e.g.,
isReplay(error)) that returns true when error is an instance of BaseError with
error.cause an instance of ContractFunctionRevertedError and
error.cause.data?.errorName === "Replay"; then replace the duplicated inline
checks in both catch sites (the blocks using the same condition) with calls to
isReplay(error), remove the redundant re-setting of the "panda.transaction" span
attribute (leave only the existing span attribute set earlier), and in the catch
blocks only set/getActiveSpan()?.setAttributes({ "panda.replay": true }) and
return c.json({ code: "ok" }) when isReplay(error) is true.

@cruzdanilo cruzdanilo marked this pull request as ready for review February 11, 2026 17:10
@cruzdanilo cruzdanilo self-requested a review as a code owner February 11, 2026 17:10
Copy link

@devin-ai-integration devin-ai-integration bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Devin Review: No Issues Found

Devin Review analyzed this PR and found no potential bugs to report.

View in Devin Review to see 4 additional findings.

Open in Devin Review

@sentry
Copy link

sentry bot commented Feb 11, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 67.73%. Comparing base (a27029d) to head (03fdfa3).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #758      +/-   ##
==========================================
+ Coverage   67.67%   67.73%   +0.06%     
==========================================
  Files         206      206              
  Lines        6932     6940       +8     
  Branches     2171     2175       +4     
==========================================
+ Hits         4691     4701      +10     
+ Misses       2052     2049       -3     
- Partials      189      190       +1     
Flag Coverage Δ
e2e 51.79% <0.00%> (-0.06%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@cruzdanilo cruzdanilo merged commit 03fdfa3 into main Feb 11, 2026
15 checks passed
@cruzdanilo cruzdanilo deleted the replay branch February 11, 2026 17:36
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.

2 participants