github.com/phobos182/packer@v0.2.3-0.20130819023704-c84d2aeffc68/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  }