Make error message wording consistent (closes #165)
check / check (push) Waiting to run

Error messages in mfer/ and internal/cli/ are lowercase except names and
acronyms, carry no "failed to" or command-name prefix, and each wrap names
only the operation and thing the wrapped error does not already name, so a
stacked message names what failed once. Wraps around errors that already
name their operation and path (os and afero path errors, url.Error, the gpg
helpers' own errors) are dropped. runGPG appends gpg's stderr only when gpg
wrote some, so no message ends in a colon. errHTTPStatus reads "unexpected
HTTP status"; both inner-not-set sentinels read "inner message not set".
No sentinel, errors.Is result or exit status changes. Message tests pin the
new text through the real call sites.

Model: opus-5-5
This commit is contained in:
2026-10-07 13:49:31 +00:00
parent 4fe1ff2fe1
commit 98c916ef20
18 changed files with 214 additions and 173 deletions
+9 -11
View File
@@ -15,17 +15,13 @@ import (
// manifestFetchTimeout bounds HTTP requests made to fetch a manifest.
const manifestFetchTimeout = 30 * time.Second
// errHTTPStatus indicates an HTTP response with a non-OK status code.
//
// Its text is the literal "HTTP" prefix of the rendered "HTTP <code>"
// message that mfer has always printed, so that wrapping it does not
// change any user-visible output. Match it with errors.Is; do not read
// its message.
var errHTTPStatus = errors.New("HTTP")
// errHTTPStatus indicates an HTTP response with a non-OK status code. It is
// followed by the code, as in "unexpected HTTP status 404".
var errHTTPStatus = errors.New("unexpected HTTP status")
// errManifestTooLarge indicates a manifest download that passed
// CLIApp.maxManifestSize.
var errManifestTooLarge = errors.New("manifest exceeds maximum allowed size")
var errManifestTooLarge = errors.New("file exceeds maximum allowed size")
// isHTTPURL returns true if the string starts with http:// or https://.
func isHTTPURL(s string) bool {
@@ -40,20 +36,22 @@ func (mfa *CLIApp) openManifestReader(
if isHTTPURL(pathOrURL) {
client := &http.Client{Timeout: manifestFetchTimeout}
// The *url.Error that NewRequestWithContext and Do return names
// the URL.
req, err := http.NewRequestWithContext(ctx, http.MethodGet, pathOrURL, nil)
if err != nil {
return nil, fmt.Errorf("failed to fetch %s: %w", pathOrURL, err)
return nil, fmt.Errorf("download manifest: %w", err)
}
resp, err := client.Do(req)
if err != nil {
return nil, fmt.Errorf("failed to fetch %s: %w", pathOrURL, err)
return nil, fmt.Errorf("download manifest: %w", err)
}
if resp.StatusCode != http.StatusOK {
_ = resp.Body.Close()
return nil, fmt.Errorf("failed to fetch %s: %w %d",
return nil, fmt.Errorf("download manifest %s: %w %d",
pathOrURL, errHTTPStatus, resp.StatusCode)
}