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