Skip to content

Better handlng of transient validation errors#111

Merged
RogerPodacter merged 4 commits into
evm-backend-demofrom
transient_validation_errors
Sep 24, 2025
Merged

Better handlng of transient validation errors#111
RogerPodacter merged 4 commits into
evm-backend-demofrom
transient_validation_errors

Conversation

@RogerPodacter

Copy link
Copy Markdown
Member

No description provided.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull Request Overview

This PR improves handling of transient validation errors by implementing retry mechanisms and better error classification. The changes distinguish between permanent validation failures and temporary infrastructure issues that should be retried.

  • Adds retry logic with exponential backoff for API calls and network timeouts
  • Introduces new error types to differentiate transient vs permanent failures
  • Implements validation stalling detection to pause imports when validation falls behind

Reviewed Changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
lib/ethscriptions_api_client.rb Adds retry mechanism with custom error types and exponential backoff
lib/block_validator.rb Introduces TransientValidationError and improves error classification
config/derive_ethscriptions_blocks.rb Handles ValidationStalledError to pause imports when validation is behind
app/services/eth_block_importer.rb Separates real validation failures from stalled validation states
app/models/validation_result.rb Updates validation persistence to handle transient errors properly
app/jobs/validation_job.rb Configures retry behavior specifically for transient validation errors
Comments suppressed due to low confidence (1)

lib/ethscriptions_api_client.rb:1

  • Unnecessary parentheses in method call. This should be @errors.empty? without parentheses.
class EthscriptionsApiClient

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

rescue HttpError, ApiError, NetworkError => e
# Wrap all internal errors into a single type for callers
Rails.logger.error "API unavailable for block #{block_number} after retries: #{e.message}"
raise ApiUnavailableError, "API unavailable after #{ENV.fetch('ETHSCRIPTIONS_API_RETRIES', 7)} retries: #{e.message}"

Copilot AI Sep 24, 2025

Copy link

Choose a reason for hiding this comment

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

The retry count should be retrieved from the same source as the retry configuration on line 85. Consider storing the retry count in a variable to avoid inconsistency.

Copilot uses AI. Check for mistakes.
def get_validation_failure_block
# Get the earliest failed block that's behind current import
def validation_stalled?
return false unless ENV.fetch('VALIDATION_ENABLED').casecmp?('true')

Copilot AI Sep 24, 2025

Copy link

Choose a reason for hiding this comment

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

This will raise a KeyError if VALIDATION_ENABLED environment variable is not set. Use ENV.fetch('VALIDATION_ENABLED', 'false') to provide a default value.

Suggested change
return false unless ENV.fetch('VALIDATION_ENABLED').casecmp?('true')
return false unless ENV.fetch('VALIDATION_ENABLED', 'false').casecmp?('true')

Copilot uses AI. Check for mistakes.
Comment thread app/models/validation_result.rb Outdated
Comment on lines +118 to +119
exception_class: e.class.name,
validated_at: Time.current

Copilot AI Sep 24, 2025

Copy link

Choose a reason for hiding this comment

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

The validated_at field is being set in both the validation_stats hash and as a separate attribute. Remove the duplicate entry from the validation_stats hash to avoid confusion.

Suggested change
exception_class: e.class.name,
validated_at: Time.current
exception_class: e.class.name

Copilot uses AI. Check for mistakes.
cursor[bot]

This comment was marked as outdated.

@RogerPodacter RogerPodacter merged commit bd6d0d7 into evm-backend-demo Sep 24, 2025
3 checks passed
@RogerPodacter RogerPodacter deleted the transient_validation_errors branch September 24, 2025 14:21
error_result.log_summary
validation_result.save!

validation_result.log_summary

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Race Condition in Concurrent Validation Jobs

The find_or_initialize_by and save! pattern introduces a race condition. Concurrent validation jobs for the same l1_block can cause uniqueness constraint violations during persistence in both success and error paths. Also, if save! fails for other database reasons, the general rescue block misclassifies it as a validation logic error.

Fix in Cursor Fix in Web

request['Accept'] = 'application/json'

begin
response = http.request(request)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug: Timeouts and Exception Handling Issues

The HTTP client no longer sets explicit open_timeout and read_timeout, which means network requests will use long default timeouts. This significantly delays retry attempts during network issues. Furthermore, the Retriable configuration redundantly includes Net::OpenTimeout and Net::ReadTimeout, as these exceptions are caught and re-raised as NetworkError before Retriable can process them directly.

Fix in Cursor Fix in Web

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