Skip to content

Commit b86cbfe

Browse files
committed
Wrap yaml decode error with friendly error message
1 parent ed8714c commit b86cbfe

1 file changed

Lines changed: 31 additions & 1 deletion

File tree

internal/config/config.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"os/exec"
88
"path/filepath"
99
"reflect"
10+
"regexp"
1011
"strconv"
1112
"strings"
1213
"time"
@@ -287,6 +288,35 @@ func defaultConfig() Config {
287288

288289
var GlobalConfig = defaultConfig()
289290

291+
// configFriendlyError maps a YAML error substring to a user-friendly hint.
292+
type configFriendlyError struct {
293+
substring string
294+
hint string
295+
}
296+
297+
var knownConfigErrors = []configFriendlyError{
298+
{
299+
substring: "cannot unmarshal !!map into string",
300+
hint: "string value is required, but a map was found. A value like {STRING} is interpreted as a YAML map, not a string. Use quotes (e.g. '{STRING}')",
301+
},
302+
}
303+
304+
var yamlLineRe = regexp.MustCompile(`line (\d+):`)
305+
306+
func wrapConfigDecodeError(configPath string, err error) error {
307+
msg := err.Error()
308+
for _, known := range knownConfigErrors {
309+
if strings.Contains(msg, known.substring) {
310+
lineInfo := ""
311+
if m := yamlLineRe.FindStringSubmatch(msg); m != nil {
312+
lineInfo = fmt.Sprintf("line %s:", m[1])
313+
}
314+
return fmt.Errorf("decode config file path %s failed: %s %s\nOriginal error: %w", configPath, lineInfo, known.hint, err)
315+
}
316+
}
317+
return fmt.Errorf("decode config file path %s failed: %w", configPath, err)
318+
}
319+
290320
func ParseFlags(args []string) error {
291321
if len(args) < 2 {
292322
return nil
@@ -317,7 +347,7 @@ func ParseFlags(args []string) error {
317347
decoder := yaml.NewDecoder(file)
318348
err = decoder.Decode(&GlobalConfig)
319349
if err != nil {
320-
return fmt.Errorf("decode config file path %s failed: %w", GlobalConfig.ConfigPath, err)
350+
return wrapConfigDecodeError(GlobalConfig.ConfigPath, err)
321351
}
322352

323353
return copyFlagsValue(&GlobalConfig.Options, result)

0 commit comments

Comments
 (0)