Skip to content

Comments

🥅 server: capture proposal reverts as warnings#808

Merged
cruzdanilo merged 1 commit intomainfrom
execute
Feb 19, 2026
Merged

🥅 server: capture proposal reverts as warnings#808
cruzdanilo merged 1 commit intomainfrom
execute

Conversation

@cruzdanilo
Copy link
Member

@cruzdanilo cruzdanilo commented Feb 19, 2026


Open with Devin

Summary by CodeRabbit

  • New Features

    • Configurable severity for transaction operations: set captures to "error", "warning", or suppress via static or dynamic rules.
  • Bug Fixes

    • Certain proposal revert failures now generate warnings (not errors) to reduce noise and surface actionable issues.
  • Tests

    • Expanded coverage for severity options, dynamic-level functions, suppression behavior, and updated expectations for warning vs error captures.
  • Chores

    • Patch release metadata added.

@changeset-bot
Copy link

changeset-bot bot commented Feb 19, 2026

🦋 Changeset detected

Latest commit: 2cc0413

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 19, 2026

Walkthrough

Adds configurable severity handling to keeper.exaSend, maps certain executeProposal contract errors to warnings, attaches proposal context (account/nonce/type/retry) to Sentry captures, and updates tests to expect the new capture levels and matching behavior.

Changes

Cohort / File(s) Summary
Release metadata
\.changeset/calm-eagles-warn.md
Adds a patch changeset documenting the change ("capture proposal reverts as warnings").
Hook implementation
server/hooks/block.ts
Attach proposal context (with Number(nonce) and proposalType) to Sentry scope; map NonceTooLow/NoProposal to non-fatal path; map ContractFunctionExecutionError captures to "warning" while other failures remain "error"; remove some per-branch captureException calls.
Hook tests
server/test/hooks/block.test.ts
Update expectations from "error" to "warning" for ContractFunctionExecutionError cases; matcher supports both inner proposal context and outer error structure; adjust zrem matcher formatting.
Keeper utility implementation
server/utils/keeper.ts
Introduce optional level option on exaSend: static ("error"
Keeper utility tests
server/test/utils/keeper.test.ts
Add tests covering level behavior: default error level, static warning, suppression via false, dynamic level function invocation and suppression when it returns false (using Viem-synthesized contract errors).

Sequence Diagram(s)

sequenceDiagram
    participant Hook as Proposal Hook
    participant Keeper as keeper.exaSend
    participant Sentry as Sentry Scope
    participant Capture as captureException

    Hook->>Keeper: call exaSend / executeProposal (error occurs)
    Note over Keeper: determine options.level
    alt level is function
        Keeper->>Keeper: computedLevel = level(reason, error)
    else level is static
        Keeper->>Keeper: computedLevel = static
    else level === false
        Keeper->>Keeper: suppress capture (end)
    else no level provided
        Keeper->>Keeper: computedLevel = "error"
    end
    alt computedLevel truthy
        Keeper->>Sentry: withScope()
        Sentry->>Sentry: fingerprint = revertFingerprint(error)
        Sentry->>Sentry: if fingerprint known -> augment event.type
        Sentry->>Capture: captureException(error, { level: computedLevel, contexts: { proposal } })
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • nfmelendez
🚥 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 directly and clearly describes the main change: implementing proposal revert capture as warnings instead of errors, which aligns with all modified files' purpose.

✏️ 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 execute

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 @cruzdanilo, 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 significantly enhances the error reporting mechanism within the server, specifically for handling proposal execution failures. By introducing a flexible level option for Sentry exception capture, it allows for more intelligent and less noisy error monitoring. This change ensures that critical issues are still highlighted, while expected or less severe revert reasons are either logged as warnings or not captured at all, improving the signal-to-noise ratio in error tracking.

Highlights

  • Refined Sentry Exception Capture: Implemented a new level option in keeper.exaSend to provide granular control over Sentry exception reporting, allowing errors to be captured as warnings, suppressed, or dynamically assigned a level based on the error reason.
  • Downgraded Proposal Revert Severity: Changed the default capture level for ContractFunctionExecutionError instances related to proposal reverts from 'error' to 'warning' in scheduleMessage.
  • Suppressed Specific Revert Captures: Configured Sentry to suppress capturing exceptions for specific proposal revert reasons like 'NonceTooLow()' and 'NoProposal()', reducing noise from expected operational flows.
  • Enhanced Sentry Context and Fingerprinting: Added detailed proposal context to Sentry scopes and improved error fingerprinting by setting the exception type based on revert reasons, aiding in better error grouping and analysis.
  • Comprehensive Test Coverage: Added new tests and updated existing ones to validate the behavior of the new level option and the revised Sentry capture logic across various error scenarios.
Changelog
  • .changeset/calm-eagles-warn.md
    • Added a new changeset file to document the patch.
  • server/hooks/block.ts
    • Added proposal context to Sentry scope for scheduleMessage.
    • Modified Sentry capture logic for scheduleMessage to use the new level option, treating NonceTooLow() and NoProposal() as non-capturable, and other ContractFunctionExecutionError as warnings.
    • Removed explicit captureException calls for NotNext, Timelocked, and default cases, as the new level option handles this.
  • server/test/hooks/block.test.ts
    • Updated tests to expect ContractFunctionExecutionError to be captured as warnings instead of errors.
    • Modified matchProposal utility to correctly match errors based on functionName and contractAddress when no proposal context is available.
  • server/test/utils/keeper.test.ts
    • Imported encodeErrorResult, getContractError, RawContractError from viem for testing.
    • Added new tests for the level option in keeper.exaSend, covering default error level, static warning level, suppression with false, and dynamic level function behavior.
  • server/utils/keeper.ts
    • Introduced a new level option to the options parameter of keeper.exaSend, allowing for error, warning, a function, or false.
    • Implemented logic to dynamically determine the Sentry capture level based on the new level option.
    • Added an event processor to Sentry scope to set the exception type based on the revert fingerprint, improving error grouping.
Activity
  • The pull request was opened by cruzdanilo.
  • The pull request description includes a Devin review badge, indicating potential AI assistance or review.
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.

@greptile-apps
Copy link

greptile-apps bot commented Feb 19, 2026

Greptile Summary

refactored error capture logic to treat proposal execution reverts as warnings instead of errors, reducing noise in error monitoring.

key changes:

  • added configurable level option to keeper.exaSend() supporting static levels ("error"/"warning"), dynamic functions, or suppression (false)
  • consolidated three separate captureException calls in proposal processing into a single level function that suppresses expected errors (NonceTooLow(), NoProposal()) and downgrades contract execution failures to warnings
  • moved proposal context setting earlier in the scope chain to ensure it propagates to all error captures
  • enhanced exception type formatting by extracting error names from fingerprints for better sentry grouping

impact:

  • contract execution reverts (slippage issues, timelocked proposals, etc.) now appear as warnings rather than errors, improving signal-to-noise ratio in monitoring
  • error capture logic is more maintainable with centralized configuration instead of scattered captureException calls

Confidence Score: 5/5

  • safe to merge with comprehensive test coverage and well-structured refactoring
  • the changes are well-implemented with excellent test coverage (105 new test lines), maintain backward compatibility, and follow established patterns. the refactoring reduces code duplication, improves maintainability, and doesn't alter functional behavior - only error reporting severity.
  • no files require special attention

Important Files Changed

Filename Overview
.changeset/calm-eagles-warn.md adds standard changeset for patch release documenting proposal revert handling improvement
server/utils/keeper.ts adds configurable level option to exaSend for controlling error capture severity (error/warning/false), with dynamic level function support and improved exception type formatting
server/hooks/block.ts consolidates error capture logic by moving proposal context earlier and using new level option to downgrade contract reverts to warnings while suppressing expected errors
server/test/hooks/block.test.ts updates test expectations to match new warning-level captures for contract errors and enhances matchProposal to handle both explicit context and error-based matching
server/test/utils/keeper.test.ts adds comprehensive test coverage for new level option including static levels, dynamic function, suppression, and correct argument passing

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[keeper.exaSend called] --> B{Execution succeeds?}
    B -->|Yes| C[Return receipt]
    B -->|No| D[Extract revert reason]
    D --> E{Check level option}
    E -->|Function| F[Call level function with reason and error]
    E -->|Static string| G[Use static level]
    E -->|false| H[Skip capture]
    E -->|undefined| G
    F --> I{Function returns?}
    I -->|false| H
    I -->|warning| J[Capture as warning]
    I -->|error| K[Capture as error]
    G --> L{Level value?}
    L -->|warning| J
    L -->|error| K
    J --> M[Apply fingerprint and type formatting]
    K --> M
    M --> N[captureException]
    H --> O[Re-throw error]
    N --> O
    
    P[Proposal execution] --> Q[Set proposal context]
    Q --> A
    Q -.context propagates.-> M
Loading

Last reviewed commit: d0ff8c6

chatgpt-codex-connector[bot]

This comment was marked as resolved.

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

gemini-code-assist[bot]

This comment was marked as resolved.

@sentry
Copy link

sentry bot commented Feb 19, 2026

Codecov Report

❌ Patch coverage is 92.85714% with 1 line in your changes missing coverage. Please review.
✅ Project coverage is 69.37%. Comparing base (55ccd09) to head (2cc0413).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
server/utils/keeper.ts 90.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #808      +/-   ##
==========================================
+ Coverage   69.34%   69.37%   +0.02%     
==========================================
  Files         208      208              
  Lines        7101     7111      +10     
  Branches     2249     2256       +7     
==========================================
+ Hits         4924     4933       +9     
  Misses       1992     1992              
- Partials      185      186       +1     
Flag Coverage Δ
e2e 52.69% <50.00%> (-0.01%) ⬇️

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.

@greptile-apps
Copy link

greptile-apps bot commented Feb 19, 2026

Greptile Summary

added configurable error severity control to the keeper utility's exaSend function, enabling proposal execution reverts to be captured as warnings instead of errors. this reduces noise in error tracking for expected revert conditions like contract execution failures.

  • added level option to keeper.exaSend that accepts static severity values ("error", "warning", false) or a function to dynamically determine severity based on revert reason and error type
  • updated proposal execution in block.ts to use the new level option, treating ContractFunctionExecutionError instances as warnings while suppressing NonceTooLow() and NoProposal() errors entirely
  • removed redundant captureException calls for NotNext and Timelocked cases since these are now handled by the centralized error capture in keeper
  • moved proposal context to the outer scope for better error context across all captures
  • enhanced exception reporting to set exception type based on revert fingerprint for improved error grouping in sentry
  • updated all tests to reflect new warning-level expectations and enhanced test matcher to handle both context-based and error-based proposal matching

Confidence Score: 4/5

  • safe to merge with minor attention to error handling changes
  • the implementation is well-designed with proper type safety and comprehensive test coverage. the changes reduce error noise by appropriately downgrading expected contract reverts to warnings. however, the refactoring consolidates error capture logic and removes explicit captures for NotNext and Timelocked cases, relying on the centralized keeper error handling. while this is cleaner, it represents a subtle behavioral change that should be monitored post-deployment to ensure all error scenarios are still being captured correctly in production.
  • pay close attention to server/hooks/block.ts to verify error capture behavior matches expectations for all revert scenarios

Important Files Changed

Filename Overview
server/utils/keeper.ts adds configurable level option to control error severity reporting for transaction reverts
server/hooks/block.ts uses new level option to report proposal execution reverts as warnings; improves context handling and removes duplicate error captures
server/test/utils/keeper.test.ts adds comprehensive tests for the new level option including static values, functions, and suppression

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[keeper.exaSend called] --> B{Simulate & Execute Transaction}
    B -->|Success| C[Return Receipt]
    B -->|Error| D[Extract Revert Reason]
    D --> E{Check ignore option}
    E -->|Ignored| F[Set OK Status]
    E -->|Not Ignored| G{Evaluate level option}
    G -->|level = function| H[Call level function with reason & error]
    G -->|level = static value| I[Use static level]
    H --> J{Function returns false?}
    J -->|true| K[Suppress Capture]
    J -->|false| L{Function returns warning or error?}
    L -->|warning| M[Capture as Warning]
    L -->|error| N[Capture as Error]
    I -->|false| K
    I -->|warning| M
    I -->|error| N
    M --> O[Set Error Status & Throw]
    N --> O
    K --> O
    
    P[executeProposal in block.ts] --> Q[keeper.exaSend with level function]
    Q --> R{Check Reason}
    R -->|NonceTooLow or NoProposal| S[Return false - suppress]
    R -->|ContractFunctionExecutionError| T[Return warning]
    R -->|Other Error| U[Return error]
Loading

Last reviewed commit: 6184b72

devin-ai-integration[bot]

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@greptile-apps
Copy link

greptile-apps bot commented Feb 19, 2026

Greptile Summary

adds configurable severity levels for blockchain transaction operations, allowing proposal reverts to be captured as warnings instead of errors for clearer diagnostics.

  • introduces level option to keeper.exaSend() supporting static ("error" | "warning" | false) or dynamic severity determination via function
  • applies dynamic level function to executeProposal operations, treating ContractFunctionExecutionError as warnings while maintaining errors for unexpected issues
  • removes duplicate captureException calls for NotNext and Timelocked cases, now captured upstream with warning level
  • standardizes nonce field in proposal context as Number(nonce) for consistency
  • adds custom event processor to update exception type based on revert fingerprint for improved sentry grouping

Confidence Score: 4/5

  • safe to merge with minimal risk - adds non-breaking feature with comprehensive tests
  • well-tested configurable severity feature with proper fallbacks, though the dynamic level logic in block.ts merits careful review to ensure all edge cases behave as intended
  • pay close attention to server/hooks/block.ts where the dynamic level function interacts with error handling flow

Important Files Changed

Filename Overview
server/utils/keeper.ts added configurable level option supporting static/dynamic severity control with proper fingerprinting
server/hooks/block.ts applied dynamic level function to proposal execution, removed duplicate captures, standardized context format
server/test/hooks/block.test.ts updated test assertions to expect warning level for contract errors, improved matcher logic consistency

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[keeper.exaSend called] --> B{Transaction succeeds?}
    B -->|Yes| C[Return receipt]
    B -->|No| D[Determine revert reason]
    D --> E{Check ignore option}
    E -->|Matches| F[Mark span OK, return null/receipt]
    E -->|No match| G{Evaluate level option}
    G -->|false| H[Suppress capture, throw error]
    G -->|function| I[Call level function with reason & error]
    G -->|static string| J[Use static level]
    I --> K{Function returns false?}
    K -->|Yes| H
    K -->|No| L[Use returned level]
    J --> L
    L --> M[Capture exception with level]
    M --> N{Has fingerprint?}
    N -->|Yes| O[Add custom event processor]
    N -->|No| P[Capture with standard fingerprint]
    O --> P
    P --> Q[Throw error]
    F --> C
    H --> Q
Loading

Last reviewed commit: 2cc0413

@cruzdanilo cruzdanilo merged commit 2cc0413 into main Feb 19, 2026
8 of 12 checks passed
@cruzdanilo cruzdanilo deleted the execute branch February 19, 2026 16:55
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: 2

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