github.com/jerryclinesmith/packer@v0.3.7/panic.go (about) 1 package main 2 3 import ( 4 "fmt" 5 "github.com/mitchellh/panicwrap" 6 "io" 7 "os" 8 "strings" 9 ) 10 11 // This is output if a panic happens. 12 const panicOutput = ` 13 14 !!!!!!!!!!!!!!!!!!!!!!!!!!! PACKER CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! 15 16 Packer crashed! This is always indicative of a bug within Packer. 17 A crash log has been placed at "crash.log" relative to your current 18 working directory. It would be immensely helpful if you could please 19 report the crash with Packer[1] so that we can fix this. 20 21 [1]: https://github.com/mitchellh/packer/issues 22 23 !!!!!!!!!!!!!!!!!!!!!!!!!!! PACKER CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! 24 ` 25 26 // panicHandler is what is called by panicwrap when a panic is encountered 27 // within Packer. It is guaranteed to run after the resulting process has 28 // exited so we can take the log file, add in the panic, and store it 29 // somewhere locally. 30 func panicHandler(logF *os.File) panicwrap.HandlerFunc { 31 return func(m string) { 32 // Write away just output this thing on stderr so that it gets 33 // shown in case anything below fails. 34 fmt.Fprintf(os.Stderr, fmt.Sprintf("%s\n", m)) 35 36 // Create the crash log file where we'll write the logs 37 f, err := os.Create("crash.log") 38 if err != nil { 39 fmt.Fprintf(os.Stderr, "Failed to create crash log file: %s", err) 40 return 41 } 42 defer f.Close() 43 44 // Seek the log file back to the beginning 45 if _, err = logF.Seek(0, 0); err != nil { 46 fmt.Fprintf(os.Stderr, "Failed to seek log file for crash: %s", err) 47 return 48 } 49 50 // Copy the contents to the crash file. This will include 51 // the panic that just happened. 52 if _, err = io.Copy(f, logF); err != nil { 53 fmt.Fprintf(os.Stderr, "Failed to write crash log: %s", err) 54 return 55 } 56 57 // Tell the user a crash occurred in some helpful way that 58 // they'll hopefully notice. 59 fmt.Printf("\n\n") 60 fmt.Println(strings.TrimSpace(panicOutput)) 61 } 62 }