chore(cmd): improves error messaging across the board

This commit is contained in:
Lewis Wynne 2025-12-17 14:49:24 +00:00
parent def2941128
commit fcae0bd4df
6 changed files with 37 additions and 47 deletions

View file

@ -24,7 +24,6 @@ package cmd
import ( import (
"errors" "errors"
"fmt" "fmt"
"path/filepath"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -46,47 +45,38 @@ func delDb(cmd *cobra.Command, args []string) error {
var notFound errNotFound var notFound errNotFound
path, err := store.FindStore(args[0]) path, err := store.FindStore(args[0])
if errors.As(err, &notFound) { if errors.As(err, &notFound) {
fmt.Fprintf(os.Stderr, "%q does not exist, %s\n", args[0], err.Error()) return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
os.Exit(1)
} }
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "unexpected error: %s", err.Error()) return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
os.Exit(1)
}
var confirm string
home, err := os.UserHomeDir()
nicepath := path
if err == nil && strings.HasPrefix(path, home) {
nicepath = filepath.Join("~", strings.TrimPrefix(nicepath, home))
} }
force, err := cmd.Flags().GetBool("force") force, err := cmd.Flags().GetBool("force")
if err != nil { if err != nil {
return err return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
} }
if force { if force {
return executeDeletion(path, nicepath) return executeDeletion(path)
} }
message := fmt.Sprintf("Are you sure you want to delete '%s'? (y/n)", nicepath) message := fmt.Sprintf("delete-db '%s': are you sure? (y/n)", args[0])
fmt.Println(message) fmt.Println(message)
var confirm string
if _, err := fmt.Scanln(&confirm); err != nil { if _, err := fmt.Scanln(&confirm); err != nil {
return err return fmt.Errorf("cannot delete-db '%s': %v", args[0], err)
} }
if strings.ToLower(confirm) == "y" { if strings.ToLower(confirm) == "y" {
return executeDeletion(path, nicepath) return executeDeletion(path)
} }
fmt.Fprintf(os.Stderr, "Did not delete %q\n", nicepath)
return nil return nil
} }
func executeDeletion(path, nicepath string) error { func executeDeletion(path string) error {
if err := os.RemoveAll(path); err != nil { if err := os.RemoveAll(path); err != nil {
return err return fmt.Errorf("cannot delete-db '%s': %v", path, err)
} }
fmt.Fprintf(os.Stderr, "Deleted %q\n", nicepath)
return nil return nil
} }

View file

@ -35,12 +35,12 @@ func dump(cmd *cobra.Command, args []string) error {
rawArg := args[0] rawArg := args[0]
dbName, err := store.parseDB(rawArg, false) dbName, err := store.parseDB(rawArg, false)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot dump '%s': %v", rawArg, err)
} }
if _, err := store.FindStore(dbName); err != nil { if _, err := store.FindStore(dbName); err != nil {
var notFound errNotFound var notFound errNotFound
if errors.As(err, &notFound) { if errors.As(err, &notFound) {
return fmt.Errorf("%q does not exist, %s", rawArg, err.Error()) return fmt.Errorf("cannot dump '%s': %v", rawArg, err)
} }
return err return err
} }
@ -49,12 +49,12 @@ func dump(cmd *cobra.Command, args []string) error {
mode, err := cmd.Flags().GetString("encoding") mode, err := cmd.Flags().GetString("encoding")
if err != nil { if err != nil {
return err return fmt.Errorf("cannot dump '%s': %v", args[0], err)
} }
switch mode { switch mode {
case "auto", "base64", "text": case "auto", "base64", "text":
default: default:
return fmt.Errorf("unsupported encoding %q", mode) return fmt.Errorf("cannot dump '%s': unsupported encoding '%s'", args[0], mode)
} }
includeSecret, err := cmd.Flags().GetBool("secret") includeSecret, err := cmd.Flags().GetBool("secret")
@ -94,7 +94,7 @@ func dump(cmd *cobra.Command, args []string) error {
encodeBase64(&entry, v) encodeBase64(&entry, v)
case "text": case "text":
if err := encodeText(&entry, key, v); err != nil { if err := encodeText(&entry, key, v); err != nil {
return err return fmt.Errorf("cannot dump '%s': %v", args[0], err)
} }
case "auto": case "auto":
if utf8.Valid(v) { if utf8.Valid(v) {
@ -106,12 +106,12 @@ func dump(cmd *cobra.Command, args []string) error {
} }
payload, err := json.Marshal(entry) payload, err := json.Marshal(entry)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot dump '%s': %v", args[0], err)
} }
fmt.Fprintln(cmd.OutOrStdout(), string(payload)) fmt.Fprintln(cmd.OutOrStdout(), string(payload))
return nil return nil
}); err != nil { }); err != nil {
return err return fmt.Errorf("cannot dump '%s': %v", args[0], err)
} }
} }
return nil return nil

View file

@ -40,7 +40,7 @@ func listDbs(cmd *cobra.Command, args []string) error {
store := &Store{} store := &Store{}
dbs, err := store.AllStores() dbs, err := store.AllStores()
if err != nil { if err != nil {
return err return fmt.Errorf("cannot list-dbs: %v", err)
} }
for _, db := range dbs { for _, db := range dbs {
fmt.Println("@" + db) fmt.Println("@" + db)

View file

@ -46,26 +46,26 @@ func list(cmd *cobra.Command, args []string) error {
rawArg := args[0] rawArg := args[0]
dbName, err := store.parseDB(rawArg, false) dbName, err := store.parseDB(rawArg, false)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot ls '%s': %v", args[0], err)
} }
if _, err := store.FindStore(dbName); err != nil { if _, err := store.FindStore(dbName); err != nil {
var notFound errNotFound var notFound errNotFound
if errors.As(err, &notFound) { if errors.As(err, &notFound) {
return fmt.Errorf("%q does not exist, %s", rawArg, err.Error()) return fmt.Errorf("cannot ls '%s': No such DB", args[0])
} }
return err return fmt.Errorf("cannot ls '%s': %v", args[0], err)
} }
targetDB = "@" + dbName targetDB = "@" + dbName
} }
flags, err := enrichFlags() flags, err := enrichFlags()
if err != nil { if err != nil {
return err return fmt.Errorf("cannot ls '%s': %v", targetDB, err)
} }
columnKinds, err := requireColumns(flags) columnKinds, err := requireColumns(flags)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot ls '%s': %v", targetDB, err)
} }
output := cmd.OutOrStdout() output := cmd.OutOrStdout()
@ -112,7 +112,7 @@ func list(cmd *cobra.Command, args []string) error {
valueBuf = append(valueBuf[:0], v...) valueBuf = append(valueBuf[:0], v...)
return nil return nil
}); err != nil { }); err != nil {
return err return fmt.Errorf("cannot ls '%s': %v", targetDB, err)
} }
valueStr = store.FormatBytes(flags.binary, valueBuf) valueStr = store.FormatBytes(flags.binary, valueBuf)
} }

View file

@ -28,14 +28,14 @@ func restore(cmd *cobra.Command, args []string) error {
if len(args) == 1 { if len(args) == 1 {
parsed, err := store.parseDB(args[0], false) parsed, err := store.parseDB(args[0], false)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot restore '%s': %v", args[0], err)
} }
dbName = parsed dbName = parsed
} }
reader, closer, err := restoreInput(cmd) reader, closer, err := restoreInput(cmd)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot restore '%s': %v", dbName, err)
} }
if closer != nil { if closer != nil {
defer closer.Close() defer closer.Close()
@ -43,7 +43,7 @@ func restore(cmd *cobra.Command, args []string) error {
db, err := store.open(dbName) db, err := store.open(dbName)
if err != nil { if err != nil {
return err return fmt.Errorf("cannot restore '%s': %v", dbName, err)
} }
defer db.Close() defer db.Close()
@ -66,15 +66,15 @@ func restore(cmd *cobra.Command, args []string) error {
var entry dumpEntry var entry dumpEntry
if err := json.Unmarshal([]byte(line), &entry); err != nil { if err := json.Unmarshal([]byte(line), &entry); err != nil {
return fmt.Errorf("line %d: %w", lineNo, err) return fmt.Errorf("cannot restore '%s': line %d: %w", dbName, lineNo, err)
} }
if entry.Key == "" { if entry.Key == "" {
return fmt.Errorf("line %d: missing key", lineNo) return fmt.Errorf("cannot restore '%s': line %d: missing key", dbName, lineNo)
} }
value, err := decodeEntryValue(entry) value, err := decodeEntryValue(entry)
if err != nil { if err != nil {
return fmt.Errorf("line %d: %w", lineNo, err) return fmt.Errorf("cannot restore '%s': line %d: %w", dbName, lineNo, err)
} }
entryMeta := byte(0x0) entryMeta := byte(0x0)
@ -85,13 +85,13 @@ func restore(cmd *cobra.Command, args []string) error {
writeEntry := badger.NewEntry([]byte(entry.Key), value).WithMeta(entryMeta) writeEntry := badger.NewEntry([]byte(entry.Key), value).WithMeta(entryMeta)
if entry.ExpiresAt != nil { if entry.ExpiresAt != nil {
if *entry.ExpiresAt < 0 { if *entry.ExpiresAt < 0 {
return fmt.Errorf("line %d: expires_at must be >= 0", lineNo) return fmt.Errorf("cannot restore '%s': line %d: expires_at must be >= 0", dbName, lineNo)
} }
writeEntry.ExpiresAt = uint64(*entry.ExpiresAt) writeEntry.ExpiresAt = uint64(*entry.ExpiresAt)
} }
if err := wb.SetEntry(writeEntry); err != nil { if err := wb.SetEntry(writeEntry); err != nil {
return fmt.Errorf("line %d: %w", lineNo, err) return fmt.Errorf("cannot restore '%s': line %d: %w", dbName, lineNo, err)
} }
restored++ restored++
} }
@ -101,7 +101,7 @@ func restore(cmd *cobra.Command, args []string) error {
} }
if err := wb.Flush(); err != nil { if err := wb.Flush(); err != nil {
return err return fmt.Errorf("cannot restore '%s': %v", dbName, err)
} }
fmt.Fprintf(cmd.ErrOrStderr(), "Restored %d entries into @%s\n", restored, dbName) fmt.Fprintf(cmd.ErrOrStderr(), "Restored %d entries into @%s\n", restored, dbName)

View file

@ -46,9 +46,9 @@ const (
func (err errNotFound) Error() string { func (err errNotFound) Error() string {
if len(err.suggestions) == 0 { if len(err.suggestions) == 0 {
return "no suggestions found" return "No such key"
} }
return fmt.Sprintf("did you mean %q", strings.Join(err.suggestions, ", ")) return fmt.Sprintf("No such key. Did you mean '%s'?", strings.Join(err.suggestions, ", "))
} }
type Store struct{} type Store struct{}
@ -189,7 +189,7 @@ func (s *Store) parseDB(v string, defaults bool) (string, error) {
if defaults { if defaults {
return "default", nil return "default", nil
} }
return "", fmt.Errorf("bad db format, use DB or @DB") return "", fmt.Errorf("cannot parse db: bad db format, use DB or @DB")
} }
return strings.ToLower(db), nil return strings.ToLower(db), nil
} }