From 01ffe0d97c0f9a8bc5ca1b3fa76477fc62ac9376 Mon Sep 17 00:00:00 2001 From: yusing Date: Sat, 19 Oct 2024 14:25:28 +0800 Subject: [PATCH] simplified error messages --- internal/config/config.go | 4 +-- internal/error/builder.go | 37 +++++++++++++++++++------- internal/error/error.go | 11 +++++--- internal/route/provider/docker.go | 2 +- internal/route/provider/file.go | 4 +-- internal/utils/serialization.go | 2 +- internal/watcher/events/event_queue.go | 2 +- 7 files changed, 43 insertions(+), 19 deletions(-) diff --git a/internal/config/config.go b/internal/config/config.go index aa318f87..66645c62 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -213,7 +213,7 @@ func (cfg *Config) loadProviders(providers *types.ProxyProviders) (outErr E.Nest } cfg.providers.Store(p.GetName(), p) errs.Add(p.LoadRoutes().Subject(filename)) - results.Addf("%d routes from %s", p.NumRoutes(), filename) + results.Addf("%d routes from %s", p.NumRoutes(), p.String()) } for name, dockerHost := range providers.Docker { p, err := proxy.NewDockerProvider(name, dockerHost) @@ -223,7 +223,7 @@ func (cfg *Config) loadProviders(providers *types.ProxyProviders) (outErr E.Nest } cfg.providers.Store(p.GetName(), p) errs.Add(p.LoadRoutes().Subject(p.GetName())) - results.Addf("%d routes from %s", p.NumRoutes(), name) + results.Addf("%d routes from %s", p.NumRoutes(), p.String()) } logger.Info(results.Build()) return diff --git a/internal/error/builder.go b/internal/error/builder.go index e0d866bf..c7d7ea1c 100644 --- a/internal/error/builder.go +++ b/internal/error/builder.go @@ -1,8 +1,8 @@ package error import ( + "errors" "fmt" - "strings" "sync" ) @@ -23,12 +23,21 @@ func NewBuilder(format string, args ...any) Builder { return Builder{&builder{message: format}} } -// adding nil / nil is no-op, -// you may safely pass expressions returning error to it. -func (b Builder) Add(err NestedError) { +// Add adds an error to the Builder. +// +// adding nil is no-op, +// +// flatten is a boolean flag to flatten the NestedError. +func (b Builder) Add(err NestedError, flatten ...bool) { if err != nil { b.Lock() - b.errors = append(b.errors, err) + if len(flatten) > 0 && flatten[0] { + for _, e := range err.extras { + b.errors = append(b.errors, &e) + } + } else { + b.errors = append(b.errors, err) + } b.Unlock() } } @@ -38,14 +47,26 @@ func (b Builder) AddE(err error) { } func (b Builder) Addf(format string, args ...any) { - b.Add(errorf(format, args...)) + if len(args) > 0 { + b.Add(errorf(format, args...)) + } else { + b.AddE(errors.New(format)) + } +} + +func (b Builder) AddRange(errs ...NestedError) { + b.Lock() + defer b.Unlock() + for _, err := range errs { + b.errors = append(b.errors, err) + } } func (b Builder) AddRangeE(errs ...error) { b.Lock() defer b.Unlock() for _, err := range errs { - b.AddE(err) + b.errors = append(b.errors, From(err)) } } @@ -59,8 +80,6 @@ func (b Builder) AddRangeE(errs ...error) { func (b Builder) Build() NestedError { if len(b.errors) == 0 { return nil - } else if len(b.errors) == 1 && !strings.ContainsRune(b.message, ' ') { - return b.errors[0].Subject(b.message) } return Join(b.message, b.errors...) } diff --git a/internal/error/error.go b/internal/error/error.go index 56ae7cc7..cd95dd83 100644 --- a/internal/error/error.go +++ b/internal/error/error.go @@ -133,7 +133,11 @@ func (ne NestedError) With(s any) NestedError { switch ss := s.(type) { case nil: return ne - case NestedError: + case *NestedErrorImpl: + if len(ss.extras) == 1 { + ne.extras = append(ne.extras, ss.extras[0]) + return ne + } return ne.withError(ss) case error: return ne.withError(From(ss)) @@ -248,10 +252,11 @@ func (ne NestedError) writeToSB(sb *strings.Builder, level int, prefix string) { return } - sb.WriteString(ne.err.Error()) if ne.subject != "" { - sb.WriteString(fmt.Sprintf(" for %q", ne.subject)) + sb.WriteString(ne.subject) + sb.WriteRune(' ') } + sb.WriteString(ne.err.Error()) if len(ne.extras) > 0 { sb.WriteRune(':') for _, extra := range ne.extras { diff --git a/internal/route/provider/docker.go b/internal/route/provider/docker.go index 9c480a9a..2d6afd87 100755 --- a/internal/route/provider/docker.go +++ b/internal/route/provider/docker.go @@ -33,7 +33,7 @@ func DockerProviderImpl(name, dockerHost string, explicitOnly bool) (ProviderImp } func (p *DockerProvider) String() string { - return "docker: " + p.name + return "docker@" + p.name } func (p *DockerProvider) NewWatcher() W.Watcher { diff --git a/internal/route/provider/file.go b/internal/route/provider/file.go index c686b61b..eefe3138 100644 --- a/internal/route/provider/file.go +++ b/internal/route/provider/file.go @@ -45,7 +45,7 @@ func (p FileProvider) String() string { func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) { routes = R.NewRoutes() - b := E.NewBuilder("file %q validation failure", p.fileName) + b := E.NewBuilder("validation failure") defer b.To(&res) entries := entry.NewProxyEntries() @@ -61,7 +61,7 @@ func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) { return } - b.Add(Validate(data)) + b.Add(Validate(data), true) return R.FromEntries(entries) } diff --git a/internal/utils/serialization.go b/internal/utils/serialization.go index 9d2e8d67..db174f9b 100644 --- a/internal/utils/serialization.go +++ b/internal/utils/serialization.go @@ -48,7 +48,7 @@ func ValidateYaml(schema *jsonschema.Schema, data []byte) E.NestedError { b := E.NewBuilder("yaml validation error") for _, e := range valErr.Causes { - b.AddE(e) + b.Addf(e.Message) } return b.Build() } diff --git a/internal/watcher/events/event_queue.go b/internal/watcher/events/event_queue.go index 616443a1..b8891ba0 100644 --- a/internal/watcher/events/event_queue.go +++ b/internal/watcher/events/event_queue.go @@ -62,7 +62,7 @@ func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan E.NestedError) { go func() { defer func() { if err := recover(); err != nil { - e.onError(E.PanicRecv("onFlush: %s", err)) + e.onError(E.PanicRecv("onFlush: %s", err).Subject(e.task.Parent().Name())) } }() e.onFlush(flushTask, queue)