From d1c4a7da8a9c75a9fc45b2b2a353ed932070d094 Mon Sep 17 00:00:00 2001 From: Boris Nagaev Date: Fri, 19 Dec 2025 13:58:59 -0300 Subject: [PATCH] loopd: test error reporting logic --- loopd/daemon.go | 15 +++++++++---- loopd/daemon_test.go | 50 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 4 deletions(-) create mode 100644 loopd/daemon_test.go diff --git a/loopd/daemon.go b/loopd/daemon.go index 8c8a9725..be05421f 100644 --- a/loopd/daemon.go +++ b/loopd/daemon.go @@ -47,6 +47,13 @@ var ( errOnlyStartOnce = fmt.Errorf("daemon can only be started once") ) +// shouldReportManagerErr determines whether a manager error should be forwarded +// to the internal error channel. Context cancellations are treated as +// non-fatal. +func shouldReportManagerErr(err error) bool { + return err != nil && !errors.Is(err, context.Canceled) +} + // ListenerCfg holds closures used to retrieve listeners for the gRPC services. type ListenerCfg struct { // grpcListener returns a TLS listener to use for the gRPC server, based @@ -892,7 +899,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { defer infof("Static address manager stopped") err := staticAddressManager.Run(d.mainCtx, initChan) - if err != nil && !errors.Is(err, context.Canceled) { + if shouldReportManagerErr(err) { d.internalErrChan <- err } }() @@ -924,7 +931,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { defer infof("Static address deposit manager stopped") err := depositManager.Run(d.mainCtx, initChan) - if err != nil && !errors.Is(err, context.Canceled) { + if shouldReportManagerErr(err) { d.internalErrChan <- err } }() @@ -956,7 +963,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { defer infof("Static address withdrawal manager stopped") err := withdrawalManager.Run(d.mainCtx, initChan) - if err != nil && !errors.Is(err, context.Canceled) { + if shouldReportManagerErr(err) { d.internalErrChan <- err } }() @@ -992,7 +999,7 @@ func (d *Daemon) initialize(withMacaroonService bool) error { infof("Starting static address loop-in manager...") defer infof("Static address loop-in manager stopped") err := staticLoopInManager.Run(d.mainCtx, initChan) - if err != nil && !errors.Is(err, context.Canceled) { + if shouldReportManagerErr(err) { d.internalErrChan <- err } }() diff --git a/loopd/daemon_test.go b/loopd/daemon_test.go new file mode 100644 index 00000000..79c87c40 --- /dev/null +++ b/loopd/daemon_test.go @@ -0,0 +1,50 @@ +package loopd + +import ( + "context" + "errors" + "fmt" + "testing" + + "github.com/stretchr/testify/require" +) + +// TestShouldReportManagerErr verifies that context cancellations are treated as +// non-fatal while other errors are reported. +func TestShouldReportManagerErr(t *testing.T) { + t.Parallel() + + tests := []struct { + name string + err error + expected bool + }{ + { + name: "nil error", + err: nil, + expected: false, + }, + { + name: "context canceled", + err: context.Canceled, + expected: false, + }, + { + name: "wrapped context canceled", + err: fmt.Errorf("wrap: %w", context.Canceled), + expected: false, + }, + { + name: "other error", + err: errors.New("boom"), + expected: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := shouldReportManagerErr(tt.err) + require.Equal(t, tt.expected, got) + }) + } +}