Give each failure one error value (closes #113)
check / check (push) Failing after 2s

internal/cli drops its copies of vault.ErrSecretNotFound, ErrVaultNotFound,
ErrVersionNotFound and ErrSecretExists and of the secret package's keychain
and Secure Enclave errors, and its second error for an unknown unlocker
type, an invalid mnemonic, a length below 1, an unsupported secret type and
an oversized secret. vault.ErrNilValueBuffer becomes
secret.ErrNilValueBuffer. Every error of secret.ReadPassphrase wraps
ErrPassphraseNotRead. ResolveGPGKeyFingerprint returns ErrGPGKeyNotFound for
a key the keyring lacks. storeInKeychain returns errNilDataBuffer. bip85's
ErrPasswordTooShort and ErrEncodedTooShort go with their unreachable checks,
as does the macOS check in macOS-only code. Tests that matched these
errors' text use errors.Is.

Model: opus-5-5
This commit is contained in:
2026-10-04 22:55:36 +00:00
parent 176095e3d1
commit 3e6ff1d8cc
28 changed files with 271 additions and 162 deletions
+37
View File
@@ -18,6 +18,43 @@ https://git.eeqj.de/sneak/secret/milestone/12
# Completed Steps
- 2026-10-04: A failure returns the same error value whichever command hits
it (https://git.eeqj.de/sneak/secret/issues/113). `internal/cli` no longer
keeps its own copies of `vault.ErrSecretNotFound`, `ErrVaultNotFound`,
`ErrVersionNotFound` and `ErrSecretExists`: `secret mv`, `rm`, `decrypt`,
`vault import`, `vault remove` and `version list`, `promote` and `rm` wrap
the `vault` errors. `errUnsupportedUnlockerType` is removed: `secret
unlocker add` gives `errInvalidUnlockerType` for an unknown type, whichever
check rejects it. Off macOS, adding a keychain or Secure Enclave unlocker
returns the `secret` package's error for it, not an `internal/cli` copy; on
macOS, the check that the system is macOS is gone, as it could never fail.
`secret vault import` gives `errInvalidMnemonicPhrase` for an invalid
mnemonic, as `init` and `vault create` do. `secret generate secret` gives
`errLengthTooSmall` for a length below 1 wherever it is checked, and
`errUnsupportedSecretType` for `--type mnemonic` too. `secret import` of a
file over 100MB wraps `errSecretTooLarge`, as `secret add` returns it.
`vault.ErrNilValueBuffer` is replaced by `secret.ErrNilValueBuffer`, which
`secret` already returned under another name. Messages are unchanged,
except that `secret decrypt` of a missing secret says "not found", as
`secret get` does, not "does not exist"; `vault import` of an invalid
mnemonic says "invalid BIP39 mnemonic phrase"; `--type mnemonic` says
"unsupported type: mnemonic (use 'secret generate mnemonic' instead)"; and
a file too large to import says
`failed to read secret from file <path>: secret too large: exceeds 100MB limit`.
Every error of `secret.ReadPassphrase` wraps `secret.ErrPassphraseNotRead`,
which supplies the words "failed to read passphrase" that its callers used
to add themselves; so two passphrases that differ now give only
"passphrases do not match", the words now follow "failed to read mnemonic:"
and "failed to read passphrase confirmation:", and a terminal read error no
longer repeats them. A GPG key the keyring does not hold gives
`secret.ErrGPGKeyNotFound`, found by gpg's status line for "No public key";
before, the message repeated "failed to resolve GPG key fingerprint" and
ended in gpg's exit status. The keychain unlocker returns `errNilDataBuffer`
for nil data; this and its test build only on macOS with cgo and were only
read. `bip85.ErrPasswordTooShort` and `ErrEncodedTooShort` are removed with
their checks: 64 bytes of entropy always give 86 Base64 or 80 Base85
characters, the most a password length may ask for. Tests that matched
these errors' text use `errors.Is`.
- 2026-10-04: Tests check which error a failure returns with `errors.Is`,
not by matching words of its message
(https://git.eeqj.de/sneak/secret/issues/49). Every exported error that