github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/util/recover.go (about)

     1  package util
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  
     7  	"github.com/mongodb/grip"
     8  	"github.com/mongodb/grip/message"
     9  )
    10  
    11  // RecoverAndLogStackTrace captures a panic stack trace and writes it
    12  // to the log file rather than allowing it to be printed to standard
    13  // error, where it would be lost (in the case of agents.)
    14  func RecoverAndLogStackTrace() {
    15  	if p := recover(); p != nil {
    16  		panicMsg, ok := p.(string)
    17  		if !ok {
    18  			panicMsg = fmt.Sprintf("%+v", panicMsg)
    19  		}
    20  		m := message.NewStackFormatted(1, "encountered panic '%s' at top level; recovering trace:", panicMsg)
    21  		grip.Alert(m)
    22  
    23  		r := m.Raw().(message.StackTrace)
    24  		for idx, f := range r.Frames {
    25  			grip.Criticalf("call #%d\n\t%s\n\t\t%s:%d", idx, f.Function, f.File, f.Line)
    26  		}
    27  
    28  		exitMsg := message.NewFormatted("hit panic '%s' at top level; exiting", panicMsg)
    29  
    30  		// check this env var so that we can avoid exiting in the test.
    31  		if os.Getenv("EVERGREEN_TEST") == "" {
    32  			grip.EmergencyFatal(exitMsg)
    33  		} else {
    34  			grip.Emergency(exitMsg)
    35  		}
    36  	}
    37  }