Skip to content

fix: log full context of anyhow::Error#6795

Merged
hanabi1224 merged 7 commits intomainfrom
hm/print-anyhow-error-context
Mar 26, 2026
Merged

fix: log full context of anyhow::Error#6795
hanabi1224 merged 7 commits intomainfrom
hm/print-anyhow-error-context

Conversation

@hanabi1224
Copy link
Contributor

@hanabi1224 hanabi1224 commented Mar 25, 2026

Summary of changes

Changes introduced in this pull request:

  • use alternative formatter (:#) for anyhow::Error in log to show full context. Check out this example

Reference issue to close (if applicable)

Closes

Other information and links

Change checklist

  • I have performed a self-review of my own code,
  • I have made corresponding changes to the documentation. All new code adheres to the team's documentation standards,
  • I have added tests that prove my fix is effective or that my feature works (if possible),
  • I have made sure the CHANGELOG is up-to-date. All user-facing changes should be reflected in this document.

Outside contributions

  • I have read and agree to the CONTRIBUTING document.
  • I have read and agree to the AI Policy document. I understand that failure to comply with the guidelines will lead to rejection of the pull request.

Summary by CodeRabbit

  • Bug Fixes

    • Improved and standardized error and log formatting across the app for clearer, more informative diagnostics during DB, network, sync, RPC, and state operations.
  • Refactor

    • Unified error-return conventions and enriched error contexts for more consistent and traceable failure reporting without changing runtime behavior or user-facing functionality.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 43968af3-1599-47f2-8c3b-f42ae4d756e0

📥 Commits

Reviewing files that changed from the base of the PR and between a5e858c and 9361c91.

📒 Files selected for processing (3)
  • src/db/car/forest.rs
  • src/db/car/many.rs
  • src/rpc/methods/chain.rs
✅ Files skipped from review due to trivial changes (2)
  • src/rpc/methods/chain.rs
  • src/db/car/forest.rs

Walkthrough

Standardized many function error-return types to the anyhow::Result<T> alias, replaced string-based error returns with anyhow::Result, swapped ad-hoc error wrapping to .context()/anyhow::bail!/direct ? propagation, and changed numerous log/error formatters from {e} to {e:#}. No functional control-flow changes.

Changes

Cohort / File(s) Summary
Result type standardization (core & state)
src/state_manager/mod.rs, src/state_manager/*, src/interpreter/vm.rs, src/state_manager/circulating_supply.rs, src/state_manager/utils.rs
Converted many public/internal signatures from Result<..., anyhow::Error> to anyhow::Result<...>; adjusted error enrichment to use .context() and simplified propagation. Review state-manager constructors, VM APIs, and context propagation.
Result type standardization (misc modules)
src/beacon/..., src/beacon/mock_beacon.rs, src/cli_shared/cli/mod.rs, src/fil_cns/*, src/genesis/mod.rs, src/message/mod.rs, src/message_pool/config.rs, src/utils/proofs_api/paramfetch.rs, src/shim/crypto.rs, src/tool/subcommands/*
Applied anyhow::Result alias across many modules (beacon, CLI, message pool, proofs API, shim, tools). Mostly signature-only changes; check public API surfaces for compile impacts.
Network / libp2p error conversions
src/chain_sync/network_context.rs, src/libp2p/behaviour.rs, src/libp2p/discovery.rs, src/libp2p/chain_exchange/message.rs, src/libp2p/service.rs
Replaced Result<..., String> with anyhow::Result<_>, adapted TryFrom error types to anyhow::Error, and used anyhow::bail!/.context(); inspect chain-exchange TryFrom impls and caller sites for propagated error-type changes.
Error formatting in logs (#{...})
src/chain/store/chain_store.rs, src/chain_sync/chain_follower.rs, src/cli/subcommands/f3_cmd.rs, src/daemon/*, src/db/*, src/dev/subcommands/*, src/libp2p/service.rs, src/libp2p_bitswap/request_manager.rs, src/message_pool/msgpool/selection.rs, src/rpc/*, src/tool/subcommands/*, src/state_migration/*, src/db/car/*
Changed many "{e}" log interpolations to the alternate/pretty "{e:#}". Verify logging consumers and any tests that assert exact log strings.
Error handling pattern updates & context
src/blocks/*, src/chain/store/errors.rs, src/db/parity_db.rs, src/message_pool/errors.rs, src/rpc/methods/eth.rs, src/rpc/methods/gas.rs, src/rpc/methods/state.rs, src/shim/state_tree.rs, src/utils/sqlite/mod.rs, src/db/car/many.rs
Replaced ad-hoc `map_err(
Callback / trait signature refinements
src/shim/actors/builtin/market/mod.rs, src/shim/actors/builtin/miner/mod.rs, src/shim/state_tree.rs
Simplified Fn callback signatures to use anyhow::Result and removed redundant wrapping; ensure callers match updated Fn types and trait impls.
Chain-exchange / TryFrom conversions (high-impact)
src/libp2p/chain_exchange/message.rs
Converted ChainExchangeResponse/TipsetBundle TryFrom/Error types from String to anyhow::Error, replaced string-based conversions with ?/.context() and anyhow::bail!. This is a dense change; review conversion failure paths and caller handling.
Misc small signature/log tweaks
src/blocks/mod.rs, src/statediff/*, src/state_migration/*, src/message_pool/errors.rs, src/state_manager/errors.rs
Mix of error-message formatting changes, payload type tweaks (e.g., Cow<'static, str>), and From<anyhow::Error> for Error conversions now storing formatted debug ({e:#}).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested reviewers

  • LesnyRumcajs
  • akaladarshi
🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The pull request title 'fix: log full context of anyhow::Error' accurately describes the main change: updating error logging throughout the codebase to use the alternate formatter '{e:#}' for displaying the full error context chain of anyhow::Error.
Docstring Coverage ✅ Passed Docstring coverage is 96.72% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch hm/print-anyhow-error-context
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch hm/print-anyhow-error-context

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

@hanabi1224 hanabi1224 marked this pull request as ready for review March 25, 2026 13:26
@hanabi1224 hanabi1224 requested a review from a team as a code owner March 25, 2026 13:26
@hanabi1224 hanabi1224 requested review from LesnyRumcajs and akaladarshi and removed request for a team March 25, 2026 13:26
@hanabi1224 hanabi1224 changed the title Hm/print anyhow error context fix: log full context of anyhow::Error Mar 25, 2026
Copy link
Contributor

@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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/chain_sync/network_context.rs (1)

214-254: ⚠️ Potential issue | 🟡 Minor

Simplify error handling by removing unnecessary anyhow error wrapping in callers.

The calls to chain_exchange_full_tipset() and chain_exchange_full_tipsets() in src/chain_sync/chain_follower.rs (lines 443 and 463) use .map_err(|e| anyhow::anyhow!(e))? to handle anyhow::Result<T>. This pattern wraps an already-wrapped anyhow::Error, converting it to a string representation and losing the original error chain.

Since both methods already return anyhow::Result<T>, simplify these to:

  • await? for direct propagation, or
  • .await.context("additional context")? if additional context is needed
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/chain_sync/network_context.rs` around lines 214 - 254, The callers of
chain_exchange_full_tipset() and chain_exchange_full_tipsets() are wrapping an
anyhow::Error into a new anyhow::Error via .map_err(|e| anyhow::anyhow!(e))?
which loses the original error chain; locate the calls to
chain_exchange_full_tipset and chain_exchange_full_tipsets in chain_follower.rs
and replace .await.map_err(|e| anyhow::anyhow!(e))? with a simple .await? to
propagate the existing anyhow::Error, or use .await.context("additional
context")? if you need to add context.
🧹 Nitpick comments (3)
src/utils/sqlite/mod.rs (1)

150-158: Consider using {e:#} for error logging to align with PR objective.

These tracing::warn! calls still use {e} format, which only displays the top-level error message. Given this PR's objective is to show full error context/chain using the {:#} formatter, these lines should be updated as well.

♻️ Suggested change
         if let Err(e) = sqlx::query("VACUUM").execute(db).await {
-            tracing::warn!("error vacuuming {name} database: {e}")
+            tracing::warn!("error vacuuming {name} database: {e:#}")
         }
         if let Err(e) = sqlx::query("PRAGMA wal_checkpoint(TRUNCATE)")
             .execute(db)
             .await
         {
-            tracing::warn!("error checkpointing {name} database wal: {e}")
+            tracing::warn!("error checkpointing {name} database wal: {e:#}")
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/utils/sqlite/mod.rs` around lines 150 - 158, Update the tracing warnings
in src/utils/sqlite/mod.rs to use the pretty/error-chain formatter so full error
context is logged: replace the "{e}" interpolations with "{e:#}" in the two
tracing::warn! calls associated with the sqlx::query("VACUUM") execute error and
the sqlx::query("PRAGMA wal_checkpoint(TRUNCATE)") execute error (the two blocks
that currently bind Err(e) and call tracing::warn!). Ensure both messages now
use {e:#} so the complete error chain is emitted.
src/db/blockstore_with_write_buffer.rs (1)

66-66: LGTM! Error formatting improvement applied correctly.

The change from {e} to {e:#} correctly applies the alternate formatter to display the full error context chain, which aligns with the PR objectives and improves debuggability.

Optional: Consider adding descriptive context to the warning message.

The warning currently logs only the error itself. Adding a brief description would improve log readability:

-            tracing::warn!("{e:#}");
+            tracing::warn!("Failed to flush buffer on drop: {e:#}");

This makes it immediately clear what operation failed, especially useful when scanning logs.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/db/blockstore_with_write_buffer.rs` at line 66, The current warning call
uses tracing::warn!("{e:#}") which only prints the error chain; update that
tracing::warn invocation to include a short descriptive context string (e.g.,
"failed to flush write buffer" or "error writing blockstore") combined with the
error variable e so logs show both what operation failed and the error chain;
locate the tracing::warn!("{e:#}") line and modify the message to include the
operation context while keeping {e:#} for full error formatting.
src/rpc/methods/eth/trace/state_diff.rs (1)

219-219: Inconsistent error formatting within the same function.

Line 219 now uses {e:#} for richer error context, but lines 230 and 240 still use {e}. For consistency with the PR's goal of printing full error chains, consider updating those as well.

Suggested diff for consistency
     let kamt: EvmStorageKamt<&DB> = match Kamt::load_with_config(&storage_cid, store, config) {
         Ok(k) => k,
         Err(e) => {
-            debug!("failed to load storage KAMT: {e}");
+            debug!("failed to load storage KAMT: {e:#}");
             return HashMap::default();
         }
     };

     let mut entries = HashMap::default();
     if let Err(e) = kamt.for_each(|key, value| {
         entries.insert(key.to_big_endian(), *value);
         Ok(())
     }) {
-        debug!("failed to iterate storage KAMT: {e}");
+        debug!("failed to iterate storage KAMT: {e:#}");
         return HashMap::default();
     }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/rpc/methods/eth/trace/state_diff.rs` at line 219, The debug log in
state_diff.rs uses rich error formatting in one place (debug!("failed to load
EVM state for storage extraction: {e:#}")) but other debug/error logs in the
same function still use plain "{e}"; update the remaining debug/error calls in
the same function (look for the other debug/error statements around the storage
extraction logic inside the function handling EVM state — e.g., the other debug
lines after the initial load attempt) to use "{e:#}" so all logs print full
error chains consistently, keeping the same message text and log level.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/libp2p/chain_exchange/message.rs`:
- Around line 140-143: The closure that maps TipsetBundle into T currently
discards the original conversion error by formatting a fresh string; instead
wrap the original error into an anyhow::Error and add context so the error chain
is preserved (e.g., replace the map_err(|e| anyhow::anyhow!("failed to convert
from tipset bundle: {e}")) with something that uses
anyhow::Error::new(e).context("failed to convert from tipset bundle") so the
original source (from T::try_from / FullTipset::try_from) is retained).

---

Outside diff comments:
In `@src/chain_sync/network_context.rs`:
- Around line 214-254: The callers of chain_exchange_full_tipset() and
chain_exchange_full_tipsets() are wrapping an anyhow::Error into a new
anyhow::Error via .map_err(|e| anyhow::anyhow!(e))? which loses the original
error chain; locate the calls to chain_exchange_full_tipset and
chain_exchange_full_tipsets in chain_follower.rs and replace .await.map_err(|e|
anyhow::anyhow!(e))? with a simple .await? to propagate the existing
anyhow::Error, or use .await.context("additional context")? if you need to add
context.

---

Nitpick comments:
In `@src/db/blockstore_with_write_buffer.rs`:
- Line 66: The current warning call uses tracing::warn!("{e:#}") which only
prints the error chain; update that tracing::warn invocation to include a short
descriptive context string (e.g., "failed to flush write buffer" or "error
writing blockstore") combined with the error variable e so logs show both what
operation failed and the error chain; locate the tracing::warn!("{e:#}") line
and modify the message to include the operation context while keeping {e:#} for
full error formatting.

In `@src/rpc/methods/eth/trace/state_diff.rs`:
- Line 219: The debug log in state_diff.rs uses rich error formatting in one
place (debug!("failed to load EVM state for storage extraction: {e:#}")) but
other debug/error logs in the same function still use plain "{e}"; update the
remaining debug/error calls in the same function (look for the other debug/error
statements around the storage extraction logic inside the function handling EVM
state — e.g., the other debug lines after the initial load attempt) to use
"{e:#}" so all logs print full error chains consistently, keeping the same
message text and log level.

In `@src/utils/sqlite/mod.rs`:
- Around line 150-158: Update the tracing warnings in src/utils/sqlite/mod.rs to
use the pretty/error-chain formatter so full error context is logged: replace
the "{e}" interpolations with "{e:#}" in the two tracing::warn! calls associated
with the sqlx::query("VACUUM") execute error and the sqlx::query("PRAGMA
wal_checkpoint(TRUNCATE)") execute error (the two blocks that currently bind
Err(e) and call tracing::warn!). Ensure both messages now use {e:#} so the
complete error chain is emitted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 469e916d-5db1-4eb6-807f-b24ddb876385

📥 Commits

Reviewing files that changed from the base of the PR and between 4539320 and e54b2a2.

📒 Files selected for processing (57)
  • src/beacon/drand.rs
  • src/beacon/mock_beacon.rs
  • src/blocks/header.rs
  • src/blocks/mod.rs
  • src/chain/store/chain_store.rs
  • src/chain/store/errors.rs
  • src/chain_sync/chain_follower.rs
  • src/chain_sync/network_context.rs
  • src/chain_sync/tipset_syncer.rs
  • src/cli/subcommands/f3_cmd.rs
  • src/cli_shared/cli/mod.rs
  • src/daemon/context.rs
  • src/daemon/db_util.rs
  • src/daemon/mod.rs
  • src/db/blockstore_with_write_buffer.rs
  • src/db/car/forest.rs
  • src/db/gc/snapshot.rs
  • src/db/parity_db.rs
  • src/dev/subcommands/mod.rs
  • src/dev/subcommands/update_checkpoints_cmd.rs
  • src/fil_cns/mod.rs
  • src/fil_cns/validation.rs
  • src/genesis/mod.rs
  • src/interpreter/mod.rs
  • src/interpreter/vm.rs
  • src/libp2p/behaviour.rs
  • src/libp2p/chain_exchange/message.rs
  • src/libp2p/discovery.rs
  • src/libp2p/service.rs
  • src/libp2p_bitswap/request_manager.rs
  • src/message/mod.rs
  • src/message_pool/config.rs
  • src/message_pool/errors.rs
  • src/message_pool/msgpool/selection.rs
  • src/rpc/error.rs
  • src/rpc/methods/chain.rs
  • src/rpc/methods/eth.rs
  • src/rpc/methods/eth/trace/state_diff.rs
  • src/rpc/methods/gas.rs
  • src/rpc/methods/state.rs
  • src/shim/actors/builtin/market/mod.rs
  • src/shim/actors/builtin/miner/mod.rs
  • src/shim/crypto.rs
  • src/shim/state_tree.rs
  • src/state_manager/circulating_supply.rs
  • src/state_manager/errors.rs
  • src/state_manager/mod.rs
  • src/state_manager/utils.rs
  • src/state_migration/common/state_migration.rs
  • src/state_migration/nv19/power.rs
  • src/state_migration/type_migrations/init/state_v9_to_v10.rs
  • src/statediff/mod.rs
  • src/statediff/resolve.rs
  • src/tool/subcommands/api_cmd.rs
  • src/tool/subcommands/snapshot_cmd.rs
  • src/utils/proofs_api/paramfetch.rs
  • src/utils/sqlite/mod.rs

@codecov
Copy link

codecov bot commented Mar 25, 2026

Codecov Report

❌ Patch coverage is 35.00000% with 130 lines in your changes missing coverage. Please review.
✅ Project coverage is 63.81%. Comparing base (36b489e) to head (9361c91).
⚠️ Report is 2 commits behind head on main.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
src/blocks/header.rs 3.22% 25 Missing and 5 partials ⚠️
src/chain_sync/network_context.rs 26.92% 18 Missing and 1 partial ⚠️
src/libp2p/chain_exchange/message.rs 53.33% 4 Missing and 3 partials ⚠️
src/shim/state_tree.rs 22.22% 2 Missing and 5 partials ⚠️
src/state_manager/mod.rs 46.15% 3 Missing and 4 partials ⚠️
src/chain_sync/tipset_syncer.rs 14.28% 5 Missing and 1 partial ⚠️
src/rpc/methods/eth.rs 0.00% 4 Missing and 1 partial ⚠️
src/libp2p/service.rs 0.00% 4 Missing ⚠️
src/statediff/mod.rs 20.00% 4 Missing ⚠️
src/cli/subcommands/f3_cmd.rs 0.00% 3 Missing ⚠️
... and 24 more
Additional details and impacted files
Files with missing lines Coverage Δ
src/beacon/drand.rs 76.21% <100.00%> (-1.41%) ⬇️
src/chain/store/errors.rs 14.28% <100.00%> (ø)
src/cli_shared/cli/mod.rs 78.94% <100.00%> (ø)
src/db/car/many.rs 67.40% <100.00%> (ø)
src/fil_cns/mod.rs 64.70% <100.00%> (ø)
src/fil_cns/validation.rs 78.75% <100.00%> (ø)
src/genesis/mod.rs 75.00% <100.00%> (ø)
src/interpreter/mod.rs 77.27% <100.00%> (ø)
src/interpreter/vm.rs 81.73% <100.00%> (ø)
src/message/mod.rs 90.56% <100.00%> (ø)
... and 46 more

... and 4 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 36b489e...9361c91. Read the comment docs.

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

Copy link
Collaborator

@akaladarshi akaladarshi left a comment

Choose a reason for hiding this comment

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

Mostly LGTM, but there are couple of concerns

@hanabi1224 hanabi1224 requested a review from akaladarshi March 25, 2026 20:35
@hanabi1224 hanabi1224 added the RPC requires calibnet RPC checks to run on CI label Mar 25, 2026
@hanabi1224 hanabi1224 enabled auto-merge March 26, 2026 09:42
@hanabi1224 hanabi1224 added this pull request to the merge queue Mar 26, 2026
Merged via the queue into main with commit 10c15a2 Mar 26, 2026
42 of 61 checks passed
@hanabi1224 hanabi1224 deleted the hm/print-anyhow-error-context branch March 26, 2026 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

RPC requires calibnet RPC checks to run on CI

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants