github.com/openshift/installer@v1.4.17/pkg/diagnostics/error.go (about)

     1  package diagnostics
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"io"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/pkg/errors"
    11  )
    12  
    13  // Err wraps diagnostics information for an error.
    14  // Err allows providing information like source, reason and message
    15  // that provides a much better user error reporting capability.
    16  type Err struct {
    17  	Orig error
    18  
    19  	// Source defines with entity is generating the error.
    20  	// It allows passing along information about where the error is being
    21  	// generated from. for example, the Asset.
    22  	Source string
    23  
    24  	// Reason is a CamelCase string that summarizes the error in one word.
    25  	// It allows easy catgeorizations of known errors.
    26  	Reason string
    27  
    28  	// Message is free-form strings which provides important details or
    29  	// diagnostics for the error. When writing messages, make sure to keep in mind
    30  	// that the audience for message is end-users who might not be experts.
    31  	Message string
    32  }
    33  
    34  // Unwrap allows the error to be unwrapped.
    35  func (e *Err) Unwrap() error { return e.Orig }
    36  
    37  // Error returns a string representation of the Err. The returned value
    38  // is expected to be a single value.
    39  // The format of the error string returned is,
    40  // `error(<Reason>) from <Source>: <Message>: <Cause of Orig>`
    41  func (e *Err) Error() string {
    42  	buf := &bytes.Buffer{}
    43  	if len(e.Source) > 0 {
    44  		fmt.Fprintf(buf, "error(%s) from %s", e.Reason, e.Source)
    45  	} else {
    46  		fmt.Fprintf(buf, "error(%s)", e.Reason)
    47  	}
    48  	if msg := strings.TrimSpace(e.Message); len(msg) > 0 {
    49  		msg = breakre.ReplaceAllString(msg, " ")
    50  		fmt.Fprintf(buf, ": %s", msg)
    51  	}
    52  	if c := errors.Cause(e.Orig); c != nil {
    53  		fmt.Fprintf(buf, ": %s", errors.Cause(e.Orig))
    54  	}
    55  	return buf.String()
    56  }
    57  
    58  // Print prints the Err to Writer in a way that is more verbose and
    59  // sectionalized.
    60  // The output looks like:
    61  // Error from <Source>:
    62  // Reason: <reason>
    63  //
    64  // Message:
    65  // <Message>
    66  //
    67  // Original:
    68  // <Orig>
    69  func (e *Err) Print(w io.Writer) {
    70  	fmt.Fprintf(w, "Error from %q\n", e.Source)
    71  	fmt.Fprintf(w, "Reason: %s\n", e.Reason)
    72  	if len(e.Message) > 0 {
    73  		fmt.Fprintf(w, "\nMessage:\n")
    74  		fmt.Fprintln(w, e.Message)
    75  	}
    76  	fmt.Fprintf(w, "\nOriginal error:\n")
    77  	fmt.Fprintln(w, e.Orig)
    78  }
    79  
    80  var breakre = regexp.MustCompile(`\r?\n`)