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