diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c2ae396..74deeee7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,7 +51,7 @@ and this project adheres to diff --git a/internal/aghalg/aghalg.go b/internal/aghalg/aghalg.go index c3b6e906..3a9b07db 100644 --- a/internal/aghalg/aghalg.go +++ b/internal/aghalg/aghalg.go @@ -24,7 +24,7 @@ func (uc UniqChecker) Add(elems ...comparable) { } } -// Merge returns a validator containing data from both v and other. +// Merge returns a checker containing data from both uc and other. func (uc UniqChecker) Merge(other UniqChecker) (merged UniqChecker) { merged = make(UniqChecker, len(uc)+len(other)) for elem, num := range uc { diff --git a/internal/home/controlinstall.go b/internal/home/controlinstall.go index b9c302ee..82598078 100644 --- a/internal/home/controlinstall.go +++ b/internal/home/controlinstall.go @@ -128,7 +128,7 @@ func (req *checkConfReq) validateWeb(uc aghalg.UniqChecker) (err error) { } // validateDNS returns error if the DNS part of the initial configuration can't -// be set. autofix is true if the port can be unbound by AdGuard Home +// be set. canAutofix is true if the port can be unbound by AdGuard Home // automatically. func (req *checkConfReq) validateDNS(uc aghalg.UniqChecker) (canAutofix bool, err error) { defer func() { err = errors.Annotate(err, "validating ports: %w") }() diff --git a/internal/home/dns.go b/internal/home/dns.go index dfd133eb..8775e152 100644 --- a/internal/home/dns.go +++ b/internal/home/dns.go @@ -54,7 +54,7 @@ func initDNSServer() (err error) { } Context.stats, err = stats.New(statsConf) if err != nil { - return fmt.Errorf("couldn't initialize statistics module") + return fmt.Errorf("init stats: %w", err) } conf := querylog.Config{ diff --git a/internal/stats/unit.go b/internal/stats/unit.go index 43119907..35d47a51 100644 --- a/internal/stats/unit.go +++ b/internal/stats/unit.go @@ -67,7 +67,29 @@ type unitDB struct { TimeAvg uint32 // usec } +// withRecovered turns the value recovered from panic if any into an error and +// combines it with the one pointed by orig. orig must be non-nil. +func withRecovered(orig *error) { + p := recover() + if p == nil { + return + } + + var err error + switch p := p.(type) { + case error: + err = fmt.Errorf("panic: %w", p) + default: + err = fmt.Errorf("panic: recovered value of type %[1]T: %[1]v", p) + } + + *orig = errors.WithDeferred(*orig, err) +} + +// createObject creates s from conf and properly initializes it. func createObject(conf Config) (s *statsCtx, err error) { + defer withRecovered(&err) + s = &statsCtx{ mu: &sync.Mutex{}, }