Handle Pubsub Panics (#4350)

* handle panics
* lint
* gaz
* preston's review
This commit is contained in:
Nishant Das 2019-12-24 12:59:08 +08:00 committed by prylabs-bulldozer[bot]
parent 53b8eb57ee
commit b337a5720c
3 changed files with 31 additions and 24 deletions

View File

@ -46,6 +46,7 @@ go_library(
"//shared:go_default_library",
"//shared/bls:go_default_library",
"//shared/bytesutil:go_default_library",
"//shared/messagehandler:go_default_library",
"//shared/params:go_default_library",
"//shared/roughtime:go_default_library",
"//shared/runutil:go_default_library",

View File

@ -12,6 +12,7 @@ import (
"github.com/prysmaticlabs/prysm/beacon-chain/core/feed"
statefeed "github.com/prysmaticlabs/prysm/beacon-chain/core/feed/state"
"github.com/prysmaticlabs/prysm/beacon-chain/p2p"
"github.com/prysmaticlabs/prysm/shared/messagehandler"
"github.com/prysmaticlabs/prysm/shared/roughtime"
"github.com/prysmaticlabs/prysm/shared/traceutil"
"go.opencensus.io/trace"
@ -175,6 +176,7 @@ func (r *Service) subscribe(topic string, validator pubsub.Validator, handle sub
// appropriate counter if the particular message fails to validate.
func wrapAndReportValidation(topic string, v pubsub.Validator) (string, pubsub.Validator) {
return topic, func(ctx context.Context, pid peer.ID, msg *pubsub.Message) bool {
defer messagehandler.HandlePanic(ctx, msg)
b := v(ctx, pid, msg)
if !b {
messageFailedValidationCounter.WithLabelValues(topic).Inc()

View File

@ -17,30 +17,7 @@ var log = logrus.WithField("prefix", "message-handler")
// SafelyHandleMessage will recover and log any panic that occurs from the
// function argument.
func SafelyHandleMessage(ctx context.Context, fn func(ctx context.Context, message proto.Message) error, msg proto.Message) {
defer func() {
if r := recover(); r != nil {
printedMsg := noMsgData
if msg != nil {
printedMsg = proto.MarshalTextString(msg)
}
log.WithFields(logrus.Fields{
"r": r,
"msg": printedMsg,
}).Error("Panicked when handling p2p message! Recovering...")
debug.PrintStack()
if ctx == nil {
return
}
if span := trace.FromContext(ctx); span != nil {
span.SetStatus(trace.Status{
Code: trace.StatusCodeInternal,
Message: fmt.Sprintf("Panic: %v", r),
})
}
}
}()
defer HandlePanic(ctx, msg)
// Fingers crossed that it doesn't panic...
if err := fn(ctx, msg); err != nil {
@ -53,3 +30,30 @@ func SafelyHandleMessage(ctx context.Context, fn func(ctx context.Context, messa
}
}
}
// HandlePanic returns a panic handler function that is used to
// capture a panic.
func HandlePanic(ctx context.Context, msg proto.Message) {
if r := recover(); r != nil {
printedMsg := noMsgData
if msg != nil {
printedMsg = proto.MarshalTextString(msg)
}
log.WithFields(logrus.Fields{
"r": r,
"msg": printedMsg,
}).Error("Panicked when handling p2p message! Recovering...")
debug.PrintStack()
if ctx == nil {
return
}
if span := trace.FromContext(ctx); span != nil {
span.SetStatus(trace.Status{
Code: trace.StatusCodeInternal,
Message: fmt.Sprintf("Panic: %v", r),
})
}
}
}