github.com/sinangedik/terraform@v0.3.5/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 output is shown if a panic happens. 13 const panicOutput = ` 14 15 !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! 16 17 Terraform crashed! This is always indicative of a bug within Terraform. 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 Terraform[1] so that we can fix this. 21 22 [1]: https://github.com/hashicorp/terraform/issues 23 24 !!!!!!!!!!!!!!!!!!!!!!!!!!! TERRAFORM CRASH !!!!!!!!!!!!!!!!!!!!!!!!!!!! 25 ` 26 27 // panicHandler is what is called by panicwrap when a panic is encountered 28 // within Terraform. 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 // Right 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 }