From b08884f85a2656a0861cc394eb8e8a5004ce73d3 Mon Sep 17 00:00:00 2001 From: Filip Borkiewicz Date: Tue, 14 Nov 2023 08:01:30 -0600 Subject: [PATCH] Log common network-related errors on debug level (#50) --- service/adapters/relay_connection.go | 67 ++++++++++++++++++++--- service/adapters/relay_connection_test.go | 26 +++++++++ 2 files changed, 86 insertions(+), 7 deletions(-) create mode 100644 service/adapters/relay_connection_test.go diff --git a/service/adapters/relay_connection.go b/service/adapters/relay_connection.go index ada5702..e767661 100644 --- a/service/adapters/relay_connection.go +++ b/service/adapters/relay_connection.go @@ -38,13 +38,10 @@ func NewRelayConnection(address domain.RelayAddress, logger logging.Logger) *Rel func (r *RelayConnection) Run(ctx context.Context) { for { if err := r.run(ctx); err != nil { - var l logging.Entry - if !errors.Is(err, websocket.ErrBadHandshake) { - l = r.logger.Error() - } else { + l := r.logger.Error() + if r.errorIsCommonAndShouldNotBeLoggedOnErrorLevel(err) { l = r.logger.Debug() } - l.WithError(err).Message("encountered an error") } @@ -57,6 +54,18 @@ func (r *RelayConnection) Run(ctx context.Context) { } } +func (r *RelayConnection) errorIsCommonAndShouldNotBeLoggedOnErrorLevel(err error) bool { + if errors.Is(err, DialError{}) { + return true + } + + if errors.Is(err, ReadMessageError{}) { + return true + } + + return false +} + func (r *RelayConnection) GetEvents(ctx context.Context, publicKey domain.PublicKey, eventKinds []domain.EventKind, maxAge *time.Duration) <-chan app.EventOrEndOfSavedEvents { r.subscriptionsMutex.Lock() defer r.subscriptionsMutex.Unlock() @@ -117,7 +126,7 @@ func (r *RelayConnection) run(ctx context.Context) error { conn, _, err := websocket.DefaultDialer.DialContext(ctx, r.address.String(), nil) if err != nil { - return errors.Wrap(err, "error dialing the relay") + return NewDialError(err) } r.setState(app.RelayConnectionStateConnected) @@ -143,7 +152,7 @@ func (r *RelayConnection) run(ctx context.Context) error { for { _, messageBytes, err := conn.ReadMessage() if err != nil { - return errors.Wrap(err, "error reading a message") + return NewReadMessageError(err) } if err := r.handleMessage(messageBytes); err != nil { @@ -308,3 +317,47 @@ type subscription struct { eventKinds []domain.EventKind maxAge *time.Duration } + +type DialError struct { + underlying error +} + +func NewDialError(underlying error) DialError { + return DialError{underlying: underlying} +} + +func (t DialError) Error() string { + return fmt.Sprintf("error dialing the relay: %s", t.underlying) +} + +func (t DialError) Unwrap() error { + return t.underlying +} + +func (t DialError) Is(target error) bool { + _, ok1 := target.(DialError) + _, ok2 := target.(*DialError) + return ok1 || ok2 +} + +type ReadMessageError struct { + underlying error +} + +func NewReadMessageError(underlying error) ReadMessageError { + return ReadMessageError{underlying: underlying} +} + +func (t ReadMessageError) Error() string { + return fmt.Sprintf("error reading a message from websocket: %s", t.underlying) +} + +func (t ReadMessageError) Unwrap() error { + return t.underlying +} + +func (t ReadMessageError) Is(target error) bool { + _, ok1 := target.(ReadMessageError) + _, ok2 := target.(*ReadMessageError) + return ok1 || ok2 +} diff --git a/service/adapters/relay_connection_test.go b/service/adapters/relay_connection_test.go new file mode 100644 index 0000000..61cd564 --- /dev/null +++ b/service/adapters/relay_connection_test.go @@ -0,0 +1,26 @@ +package adapters_test + +import ( + "testing" + + "github.com/boreq/errors" + "github.com/planetary-social/nos-crossposting-service/internal/fixtures" + "github.com/planetary-social/nos-crossposting-service/service/adapters" + "github.com/stretchr/testify/require" +) + +func TestDialErrorIs(t *testing.T) { + err := adapters.NewDialError(fixtures.SomeError()) + require.ErrorIs(t, err, adapters.DialError{}) + require.ErrorIs(t, err, &adapters.DialError{}) + require.ErrorIs(t, errors.Wrap(err, "wrapped"), adapters.DialError{}) + require.ErrorIs(t, errors.Wrap(err, "wrapped"), &adapters.DialError{}) +} + +func TestReadMessageErrorIs(t *testing.T) { + err := adapters.NewReadMessageError(fixtures.SomeError()) + require.ErrorIs(t, err, adapters.ReadMessageError{}) + require.ErrorIs(t, err, &adapters.ReadMessageError{}) + require.ErrorIs(t, errors.Wrap(err, "wrapped"), adapters.ReadMessageError{}) + require.ErrorIs(t, errors.Wrap(err, "wrapped"), &adapters.ReadMessageError{}) +}