simplified error messages

This commit is contained in:
yusing 2024-10-19 14:25:28 +08:00
parent bd732dfa0a
commit 01ffe0d97c
7 changed files with 43 additions and 19 deletions

View file

@ -213,7 +213,7 @@ func (cfg *Config) loadProviders(providers *types.ProxyProviders) (outErr E.Nest
} }
cfg.providers.Store(p.GetName(), p) cfg.providers.Store(p.GetName(), p)
errs.Add(p.LoadRoutes().Subject(filename)) 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 { for name, dockerHost := range providers.Docker {
p, err := proxy.NewDockerProvider(name, dockerHost) 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) cfg.providers.Store(p.GetName(), p)
errs.Add(p.LoadRoutes().Subject(p.GetName())) 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()) logger.Info(results.Build())
return return

View file

@ -1,8 +1,8 @@
package error package error
import ( import (
"errors"
"fmt" "fmt"
"strings"
"sync" "sync"
) )
@ -23,12 +23,21 @@ func NewBuilder(format string, args ...any) Builder {
return Builder{&builder{message: format}} return Builder{&builder{message: format}}
} }
// adding nil / nil is no-op, // Add adds an error to the Builder.
// you may safely pass expressions returning error to it. //
func (b Builder) Add(err NestedError) { // 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 { if err != nil {
b.Lock() 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() b.Unlock()
} }
} }
@ -38,14 +47,26 @@ func (b Builder) AddE(err error) {
} }
func (b Builder) Addf(format string, args ...any) { 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) { func (b Builder) AddRangeE(errs ...error) {
b.Lock() b.Lock()
defer b.Unlock() defer b.Unlock()
for _, err := range errs { 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 { func (b Builder) Build() NestedError {
if len(b.errors) == 0 { if len(b.errors) == 0 {
return nil 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...) return Join(b.message, b.errors...)
} }

View file

@ -133,7 +133,11 @@ func (ne NestedError) With(s any) NestedError {
switch ss := s.(type) { switch ss := s.(type) {
case nil: case nil:
return ne 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) return ne.withError(ss)
case error: case error:
return ne.withError(From(ss)) return ne.withError(From(ss))
@ -248,10 +252,11 @@ func (ne NestedError) writeToSB(sb *strings.Builder, level int, prefix string) {
return return
} }
sb.WriteString(ne.err.Error())
if ne.subject != "" { 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 { if len(ne.extras) > 0 {
sb.WriteRune(':') sb.WriteRune(':')
for _, extra := range ne.extras { for _, extra := range ne.extras {

View file

@ -33,7 +33,7 @@ func DockerProviderImpl(name, dockerHost string, explicitOnly bool) (ProviderImp
} }
func (p *DockerProvider) String() string { func (p *DockerProvider) String() string {
return "docker: " + p.name return "docker@" + p.name
} }
func (p *DockerProvider) NewWatcher() W.Watcher { func (p *DockerProvider) NewWatcher() W.Watcher {

View file

@ -45,7 +45,7 @@ func (p FileProvider) String() string {
func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) { func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) {
routes = R.NewRoutes() routes = R.NewRoutes()
b := E.NewBuilder("file %q validation failure", p.fileName) b := E.NewBuilder("validation failure")
defer b.To(&res) defer b.To(&res)
entries := entry.NewProxyEntries() entries := entry.NewProxyEntries()
@ -61,7 +61,7 @@ func (p *FileProvider) LoadRoutesImpl() (routes R.Routes, res E.NestedError) {
return return
} }
b.Add(Validate(data)) b.Add(Validate(data), true)
return R.FromEntries(entries) return R.FromEntries(entries)
} }

View file

@ -48,7 +48,7 @@ func ValidateYaml(schema *jsonschema.Schema, data []byte) E.NestedError {
b := E.NewBuilder("yaml validation error") b := E.NewBuilder("yaml validation error")
for _, e := range valErr.Causes { for _, e := range valErr.Causes {
b.AddE(e) b.Addf(e.Message)
} }
return b.Build() return b.Build()
} }

View file

@ -62,7 +62,7 @@ func (e *EventQueue) Start(eventCh <-chan Event, errCh <-chan E.NestedError) {
go func() { go func() {
defer func() { defer func() {
if err := recover(); err != nil { 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) e.onFlush(flushTask, queue)