Skip to content

WithTxn reports rollback errors incorrectly and double-wraps the returned error #1765

Description

@AmanGIT07

Where: pkg/db/db.go, Client.WithTxn

When the transaction callback returns an error, the deferred cleanup rolls the transaction back and wraps the error before returning it:

} else if err != nil {
    if rlbErr := txn.Rollback(); err != nil {
        err = fmt.Errorf("rollback error: %s while executing: %w", rlbErr, err)
    } else {
        err = fmt.Errorf("rollback: %w", err)
    }
    err = fmt.Errorf("rollback: %w", err)
}

Two problems:

  1. The inner if condition checks err, which is always non-nil in this branch. It should check rlbErr. Because of this the else branch is unreachable, and when the rollback succeeds the message still embeds the nil rollback error:
    rollback: rollback error: %!s(<nil>) while executing: <original error>
  2. The error gets a second rollback: wrap after the inner if/else, so every error is prefixed twice.

Expected behavior:

  • Rollback succeeds: return the original error with a single wrap, e.g. rollback: <original error>.
  • Rollback fails: return both errors with a single wrap, e.g. rollback error: <rollback error> while executing: <original error>.
  • The original error stays matchable with errors.Is/errors.As (keep %w).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions