Skip to content

Commit

Permalink
rfq: only shut down on critical error
Browse files Browse the repository at this point in the history
Fixes #1010.

With this commit we introduce a new fn.CriticalError type and only send
RFQ errors to the main error channel (which causes the daemon to shut
down) if an error is critical to the operation and can't just be logged.
  • Loading branch information
guggero committed Jul 11, 2024
1 parent 4ed9ef9 commit e55d999
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 11 deletions.
40 changes: 40 additions & 0 deletions fn/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package fn

import (
"context"
"errors"
"strings"

"google.golang.org/grpc/codes"
Expand Down Expand Up @@ -44,3 +45,42 @@ func IsRpcErr(err error, candidate error) bool {

return strings.Contains(err.Error(), candidate.Error())
}

// CriticalError is an error type that should be used for errors that are
// critical and should cause the application to exit.
type CriticalError struct {
Err error
}

// NewCriticalError creates a new CriticalError instance.
func NewCriticalError(err error) *CriticalError {
return &CriticalError{Err: err}
}

// Error implements the error interface.
func (e *CriticalError) Error() string {
return e.Err.Error()
}

// Unwrap implements the errors.Wrapper interface.
func (e *CriticalError) Unwrap() error {
return e.Err
}

// ErrorAs behaves the same as `errors.As` except there's no need to declare
// the target error as a variable first.
// Instead of writing:
//
// var targetErr *TargetErr
// errors.As(err, &targetErr)
//
// We can write:
//
// lnutils.ErrorAs[*TargetErr](err)
//
// To save us from declaring the target error variable.
func ErrorAs[Target error](err error) bool {
var targetErr Target

return errors.As(err, &targetErr)
}
39 changes: 28 additions & 11 deletions rfq/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,18 @@ func (m *Manager) startSubsystems(ctx context.Context) error {
return err
}

// handleError logs an error and sends it to the main server error channel if
// it is a critical error.
func (m *Manager) handleError(err error) {
log.Errorf("Error in RFQ manager: %v", err)

// If the error is a critical error, send it to the main server error
// channel, which will cause the daemon to shut down.
if fn.ErrorAs[*fn.CriticalError](err) {
m.cfg.ErrChan <- err
}
}

// Start attempts to start a new RFQ manager.
func (m *Manager) Start() error {
var startErr error
Expand Down Expand Up @@ -363,8 +375,10 @@ func (m *Manager) handleIncomingMessage(incomingMsg rfqmsg.IncomingMsg) error {
*msg.Request.AssetID, msg.Peer,
)
if err != nil {
m.cfg.ErrChan <- fmt.Errorf("error adding "+
"local alias: %w", err)
m.handleError(fn.NewCriticalError(
fmt.Errorf("error adding "+
"local alias: %w", err),
))
return
}

Expand Down Expand Up @@ -556,8 +570,10 @@ func (m *Manager) mainEventLoop() {

err := m.handleIncomingMessage(incomingMsg)
if err != nil {
m.cfg.ErrChan <- fmt.Errorf("failed to "+
"handle incoming message: %w", err)
m.handleError(
fmt.Errorf("failed to handle "+
"incoming message: %w", err),
)
}

// Handle outgoing message.
Expand All @@ -567,8 +583,10 @@ func (m *Manager) mainEventLoop() {

err := m.handleOutgoingMessage(outgoingMsg)
if err != nil {
m.cfg.ErrChan <- fmt.Errorf("failed to "+
"handle outgoing message: %w", err)
m.handleError(
fmt.Errorf("failed to handle outgoing "+
"message: %w", err),
)
}

case acceptHtlcEvent := <-m.acceptHtlcEvents:
Expand All @@ -577,12 +595,11 @@ func (m *Manager) mainEventLoop() {

// Handle subsystem errors.
case err := <-m.subsystemErrChan:
log.Errorf("Manager main event loop received "+
"subsystem error: %v", err)

// Report the subsystem error to the main server.
m.cfg.ErrChan <- fmt.Errorf("encountered RFQ "+
"subsystem error: %w", err)
m.handleError(
fmt.Errorf("encountered RFQ subsystem error "+
"in main event loop: %w", err),
)

case <-m.Quit:
log.Debug("Manager main event loop has received the " +
Expand Down

0 comments on commit e55d999

Please sign in to comment.