Skip to content

feat(core): implement DeepestErrorFinder for root error detection - #382

Merged
codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
codewithzubair07:feature/378-deepest-error-finder
Jul 29, 2026
Merged

feat(core): implement DeepestErrorFinder for root error detection#382
codeZe-us merged 1 commit into
Toolbox-Lab:mainfrom
codewithzubair07:feature/378-deepest-error-finder

Conversation

@codewithzubair07

@codewithzubair07 codewithzubair07 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Implement DeepestErrorFinder to identify the deepest failing event in the diagnostic tree
  • Track call depth to determine the root failure
  • Return the failing ContractId and error code for improved error reporting

Closes #378

Summary by CodeRabbit

  • New Features

    • Added deepest root-cause analysis for diagnostic event cascades.
    • Reports the deepest failing contract, function name when available, call depth, and contract error code when applicable.
    • Added a convenient API for retrieving the deepest detected failure.
  • Bug Fixes

    • Improved failure detection across nested contract call sequences, including failures occurring before a function call.

@drips-wave

drips-wave Bot commented Jul 29, 2026

Copy link
Copy Markdown

@codewithzubair07 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Deepest error analysis

Layer / File(s) Summary
Shared chain-analysis helpers
crates/core/src/decode/chain_analyzer.rs
Topic parsing, failure detection, and hash-to-strkey conversion were moved to reusable free functions and wired into ChainAnalyzer.
Deepest failure finder and validation
crates/core/src/decode/chain_analyzer.rs
DeepestError, DeepestErrorFinder, and find_deepest_error scan diagnostic events by call depth, extract contract error codes, and cover ordering, ties, empty input, and default behavior in tests.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DiagnosticEvents
  participant DeepestErrorFinder
  participant CallStack
  participant DeepestError
  DiagnosticEvents->>DeepestErrorFinder: scan call and failure events
  DeepestErrorFinder->>CallStack: update depth from fn_call and fn_return
  DeepestErrorFinder->>DeepestError: select deepest failure and error code
Loading

Possibly related issues

  • #350 — The PR adds the requested deepest nested failure analysis based on event call depth.

Suggested reviewers: killerjunior

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding DeepestErrorFinder for root error detection.
Linked Issues check ✅ Passed The changes implement deepest-failure traversal, call-depth tracking, and error/ContractId extraction as requested in #378.
Out of Scope Changes check ✅ Passed The refactor of helper functions and added tests support the new finder feature and appear in scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Fix failing CI checks
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🧹 Nitpick comments (1)
crates/core/src/decode/chain_analyzer.rs (1)

454-485: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Optional: extract the shared call-stack bookkeeping.

Lines 454-485 duplicate analyze's loop head (Lines 199-235) verbatim. A small helper (e.g. fn apply_stack_event(stack: &mut Vec<StackFrame>, event, topics) -> bool returning whether the event was consumed) would keep the two analyzers from drifting, which matters since both rely on identical depth semantics.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/core/src/decode/chain_analyzer.rs` around lines 454 - 485, Extract the
duplicated call-stack handling from analyze and the shown event loop into a
shared helper, such as apply_stack_event, that accepts the stack, event, and
topics and returns whether the event was consumed. Move the fn_call and
fn_return logic, including StackFrame depth semantics and address resolution,
into that helper, then have both loops invoke it and continue when it returns
true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/core/src/decode/chain_analyzer.rs`:
- Around line 490-491: Update the failure-handling logic around is_failure to
derive depth from the relevant StackFrame's zero-based depth field instead of
using stack.len(). Ensure DeepestError::depth and the reported frame retain the
existing frame-depth semantics, and update the affected depth assertion/comment
expectations from 1 to 0 where they describe top-level failures.

---

Nitpick comments:
In `@crates/core/src/decode/chain_analyzer.rs`:
- Around line 454-485: Extract the duplicated call-stack handling from analyze
and the shown event loop into a shared helper, such as apply_stack_event, that
accepts the stack, event, and topics and returns whether the event was consumed.
Move the fn_call and fn_return logic, including StackFrame depth semantics and
address resolution, into that helper, then have both loops invoke it and
continue when it returns true.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4d6fca50-7601-4b6e-a516-4f8efcb52c3d

📥 Commits

Reviewing files that changed from the base of the PR and between 72bb2b7 and 0d987a9.

📒 Files selected for processing (1)
  • crates/core/src/decode/chain_analyzer.rs

Comment on lines +490 to +491
if is_failure(event, &topics, &v0.data) {
let depth = stack.len();

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

Off-by-one in depth: frame count vs. frame depth.

StackFrame::depth is assigned stack.len() before the push (Line 476), so a 3-frame stack has depths 0,1,2. Here depth = stack.len() yields 3, contradicting the DeepestError::depth doc ("0 = top-level") and the reported frame at Line 502. This also breaks the assertions at Lines 921 and 944, which expect 2 for a three-deep cascade.

Also, the comment at Line 964 ("Both failures are at depth 1") should read depth 0 once the semantics are corrected.

🐛 Proposed fix: derive depth from the frame, not the frame count
             if is_failure(event, &topics, &v0.data) {
-                let depth = stack.len();
+                // Use the executing frame's own depth (0 = top-level) so this
+                // matches `StackFrame::depth` and `ChainFrame::depth`.
+                let depth = stack.last().map_or(0, |frame| frame.depth);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if is_failure(event, &topics, &v0.data) {
let depth = stack.len();
if is_failure(event, &topics, &v0.data) {
// Use the executing frame's own depth (0 = top-level) so this
// matches `StackFrame::depth` and `ChainFrame::depth`.
let depth = stack.last().map_or(0, |frame| frame.depth);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/core/src/decode/chain_analyzer.rs` around lines 490 - 491, Update the
failure-handling logic around is_failure to derive depth from the relevant
StackFrame's zero-based depth field instead of using stack.len(). Ensure
DeepestError::depth and the reported frame retain the existing frame-depth
semantics, and update the affected depth assertion/comment expectations from 1
to 0 where they describe top-level failures.

@codeZe-us
codeZe-us self-requested a review July 29, 2026 13:18
@codeZe-us
codeZe-us merged commit bf0ce06 into Toolbox-Lab:main Jul 29, 2026
2 of 3 checks passed
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.

DeepestErrorFinder: pinpoint root via event depth

2 participants