Tests assert on error message fragments, never on sentinel identity — error-handling regressions pass silently #49
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Surfaced by the adversarial review of PR #29 (see #29 (comment)). Filed separately because it is a standing weakness in the suite, not a defect of that PR.
Problem
The
err113refactor introduced eleven exported sentinel errors, primarily in the newinternal/vault/errors.go. There is not a singleerrors.Isorerrors.Ascall in any test file in the repository.Error assertions are instead loose substring checks —
assert.Containson a fragment of the message text. The review demonstrated the concrete consequence: sixteen user-visible error messages had their interpolated values moved to the tail (secret X not foundbecomingsecret not found: X), and every affected test still passed, because the asserted fragment survives the reorder. The suite could not have caught the regression it exists to catch.Two distinct failure modes follow from this, and the second is the one that matters:
ErrSecretNotFoundis what actually comes back rather than some other error whose text happens to contain the same words. A refactor that returns the wrong sentinel, wraps with%vinstead of%wand severs the chain, or collapses two distinct conditions into one error passes green. In this tool the branches that depend on distinguishing errors include "secret does not exist" versus "secret exists but could not be decrypted" — conflating those is the difference between a clear message and a user concluding their data is corrupt.Substring assertions also make the messages themselves load-bearing: a wording improvement (#47 proposes several) breaks tests for no good reason, which creates pressure to leave bad messages alone.
Definition of done
errors.Is(orerrors.Aswhere the type carries data), notassert.Containson the message.internal/vault/errors.goand elsewhere has at least one test proving the function under test actually returns it.errors.Isstill reaches the underlying error, so a future%w-to-%vregression is caught.make checkgreen.TODO.mdupdated in the same commit.Implementation requirements
errors.Isbecause it was never given a sentinel, that is a real finding: report it on this issue rather than quietly adding a sentinel as a side effect.testifylintin the canonical config has a rule covering error-assertion style. If it does and it is currently satisfied by the loose assertions, note that on this issue — it would mean the linter is not helping here and the gap is purely a review-discipline matter.