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