Skip to content

Developer experience: error handling, logging, and internals #13

@don-petry

Description

@don-petry

Summary

Internal quality improvements that affect debugging, maintainability, and the developer experience when things go wrong.

Items

1. No custom error type

All errors are io::Error::other(string) — no structured variants, no error chaining, no ability to programmatically distinguish error kinds. Consider adopting thiserror with a DaggerError enum:

#[derive(thiserror::Error, Debug)]
enum DaggerError {
    #[error("branch '{0}' is not tracked")]
    BranchNotTracked(String),
    #[error("operation in progress, run --continue or --abort")]
    PendingOperation,
    #[error("git: {0}")]
    Git(#[source] io::Error),
    // ...
}

2. No logging/tracing framework

Zero debug output anywhere in the codebase. When something fails, there is no way to get verbose diagnostics. Consider tracing with a DAGGER_LOG env var (or --verbose flag) to enable debug output.

3. No dgr diff command

Can't see the diff between a branch and its tracked parent without manually looking up the parent name. A dgr diff that defaults to diffing against the tracked parent would be natural.

4. Trunk branch immutable after init

If dgr init is run on the wrong branch, the only fix is manually editing .git/.dagger/config.json. A dgr config trunk <branch> or dgr init --trunk <branch> would help.

5. ratatui is unused dead weight

Cargo.toml declares ratatui = "0.30.0" and palette.rs has #[allow(dead_code)]. The dependency adds compile time and binary size for no current benefit. Either remove it until a TUI is implemented, or gate it behind a cargo feature flag.

6. Archived nodes never pruned from state

archived: true soft-deletes nodes but they remain in state.json forever. Over time, the file grows unboundedly. Consider pruning nodes that have been archived for > N days, or adding a dgr gc command.

7. DaggerState.nodes is a Vec — O(n) lookups

find_branch_by_name and find_branch_by_id do linear scans. For typical stacks (< 20 branches) this is fine, but a HashMap<Uuid, BranchNode> would be more idiomatic and future-proof.

8. Missing event types in event log

The event log captures BranchCreated, BranchAdopted, BranchArchived, BranchReparented, BranchPullRequestTracked — but is missing events for several important state changes:

  • BranchRestacked
  • BranchPushed
  • BranchMerged
  • PullRequestRetargeted
  • SyncCompleted

9. No event log reader

Events are written to events.ndjson but never read. A dgr log command to view the audit trail would aid debugging and provide history.

10. No distinct exit codes

exit_code_from_result returns either 0 (success) or 1 (failure). Distinct codes for different failure modes (2 = usage error, 3 = conflict, 4 = pending operation, etc.) would improve scriptability.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions