github.com/prysmaticlabs/prysm@v1.4.4/shared/messagehandler/messagehandler.go (about)

     1  // Package messagehandler contains useful helpers for recovering
     2  // from panic conditions at runtime and logging their trace.
     3  package messagehandler
     4  
     5  import (
     6  	"context"
     7  	"fmt"
     8  	"runtime/debug"
     9  
    10  	pubsub "github.com/libp2p/go-libp2p-pubsub"
    11  	"github.com/sirupsen/logrus"
    12  	"go.opencensus.io/trace"
    13  )
    14  
    15  const noMsgData = "message contains no data"
    16  
    17  var log = logrus.WithField("prefix", "message-handler")
    18  
    19  // SafelyHandleMessage will recover and log any panic that occurs from the
    20  // function argument.
    21  func SafelyHandleMessage(ctx context.Context, fn func(ctx context.Context, message *pubsub.Message) error, msg *pubsub.Message) {
    22  	defer HandlePanic(ctx, msg)
    23  
    24  	// Fingers crossed that it doesn't panic...
    25  	if err := fn(ctx, msg); err != nil {
    26  		// Report any error on the span, if one exists.
    27  		if span := trace.FromContext(ctx); span != nil {
    28  			span.SetStatus(trace.Status{
    29  				Code:    trace.StatusCodeInternal,
    30  				Message: err.Error(),
    31  			})
    32  		}
    33  	}
    34  }
    35  
    36  // HandlePanic returns a panic handler function that is used to
    37  // capture a panic.
    38  func HandlePanic(ctx context.Context, msg *pubsub.Message) {
    39  	if r := recover(); r != nil {
    40  		printedMsg := noMsgData
    41  		if msg != nil {
    42  			printedMsg = msg.String()
    43  		}
    44  		log.WithFields(logrus.Fields{
    45  			"r":   r,
    46  			"msg": printedMsg,
    47  		}).Error("Panicked when handling p2p message! Recovering...")
    48  
    49  		debug.PrintStack()
    50  
    51  		if ctx == nil {
    52  			return
    53  		}
    54  		if span := trace.FromContext(ctx); span != nil {
    55  			span.SetStatus(trace.Status{
    56  				Code:    trace.StatusCodeInternal,
    57  				Message: fmt.Sprintf("Panic: %v", r),
    58  			})
    59  		}
    60  	}
    61  }