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 }