unionlabs/union · error · anyhow::Error

get_logs RPC error: {}

Error message

get_logs RPC error: {}

What it means

In `EvmClient::wait_for_event`, each one-block-wide `eth_getLogs` filter on the IBC handler address that returns a provider error is converted immediately into this message, aborting the whole wait — no retry is attempted at this level.

Source

Thrown at tools/union-test/src/evm.rs:173

                if events.len() >= expected_event_count {
                    return Ok(events);
                }

                if prev_latest >= latest {
                    tokio::time::sleep(Duration::from_secs(10)).await;
                    continue;
                }

                while prev_latest <= latest {
                    let filter = Filter::new()
                        .address(alloy::primitives::Address::from(self.ibc_handler_address))
                        .from_block(prev_latest)
                        .to_block(prev_latest);

                    let logs = match self.provider.get_logs(&filter).await {
                        Ok(logs) => logs,
                        Err(e) => {
                            return Err(anyhow::anyhow!("get_logs RPC error: {}", e));
                        }
                    };
                    for log in logs {
                        if let Ok(ibc_event) = IbcEvents::decode_log(&log.inner)
                            && let Some(event) = filter_fn(ibc_event.data)
                        {
                            events.push(event);
                        }
                    }

                    prev_latest += 1u64;
                }

                tokio::time::sleep(Duration::from_secs(10)).await;
            }
        })
        .await
        .map_err(|_| anyhow::anyhow!("timed out after {:?}", timeout))?

View on GitHub (pinned to 031785bb6d)

Solutions

  1. Point the provider at a healthy RPC endpoint (own node or paid tier) and re-run
  2. If transient, retry the wait call; or patch a retry-with-backoff around get_logs
  3. Check provider rate limits / API key configuration

Example fix

// before
let logs = self.provider.get_logs(&filter).await
    .map_err(|e| anyhow::anyhow!("get_logs RPC error: {}", e))?; 
// after: retry transient provider errors
let mut last = None;
let logs = loop {
    match self.provider.get_logs(&filter).await {
        Ok(logs) => break logs,
        Err(e) if retries_left(&mut n) => { tokio::time::sleep(Duration::from_secs(2)).await; last = Some(e); }
        Err(e) => return Err(anyhow::anyhow!("get_logs RPC error: {}", e)),
    }
};
Defensive patterns

Strategy: retry

Validate before calling

// pre-flight: provider answers a cheap call before starting the event wait
let _n = evm.provider.get_block_number().await?; // fails fast on a dead endpoint

Try / catch

let mut n = 0;
let logs = loop {
    match provider.get_logs(&filter).await {
        Ok(logs) => break logs,
        Err(e) if n < 3 => { n += 1; tokio::time::sleep(Duration::from_secs(2)).await; }
        Err(e) => return Err(anyhow::anyhow!("get_logs RPC error: {}", e)),
    }
};

Prevention

When it happens

Trigger: The RPC endpoint errors on eth_getLogs: node temporarily down or overloaded; rate limiting on a free/public endpoint; method restricted by the provider; transient network failure between the test and the node.

Common situations: Shared public RPC under load; local anvil/geth restarting mid-test; provider requiring API keys or allowlists; aggressive block-polling hitting provider quotas.

Related errors


AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16). Data as JSON: /api/errors/226a6af4a7241925. Report an issue: GitHub.