github.com/ssgreg/logf@v1.4.1/error.go (about)

     1  package logf
     2  
     3  import "fmt"
     4  
     5  // ErrorEncoder is the function type to encode the given error.
     6  type ErrorEncoder func(string, error, FieldEncoder)
     7  
     8  // DefaultErrorEncoder encodes the given error as a set of fields.
     9  //
    10  // A mandatory field with the given key and an optional field with the
    11  // full verbose error message.
    12  func DefaultErrorEncoder(key string, err error, enc FieldEncoder) {
    13  	NewErrorEncoder.Default()(key, err, enc)
    14  }
    15  
    16  // ErrorEncoderConfig allows to configure ErrorEncoder.
    17  type ErrorEncoderConfig struct {
    18  	VerboseFieldSuffix string
    19  	NoVerboseField     bool
    20  }
    21  
    22  // WithDefaults returns the new config in which all uninitialized fields are
    23  // filled with their default values.
    24  func (c ErrorEncoderConfig) WithDefaults() ErrorEncoderConfig {
    25  	if c.VerboseFieldSuffix == "" {
    26  		c.VerboseFieldSuffix = ".verbose"
    27  	}
    28  
    29  	return c
    30  }
    31  
    32  // NewErrorEncoder creates the new instance of the ErrorEncoder with the
    33  // given ErrorEncoderConfig.
    34  var NewErrorEncoder = errorEncoderGetter(
    35  	func(c ErrorEncoderConfig) ErrorEncoder {
    36  		return func(key string, err error, enc FieldEncoder) {
    37  			encodeError(key, err, enc, c.WithDefaults())
    38  		}
    39  	},
    40  )
    41  
    42  type errorEncoderGetter func(c ErrorEncoderConfig) ErrorEncoder
    43  
    44  func (c errorEncoderGetter) Default() ErrorEncoder {
    45  	return c(ErrorEncoderConfig{})
    46  }
    47  
    48  // encodeError encodes the given error as a set of fields.
    49  //
    50  // A mandatory field with the given key and an optional field with the
    51  // full verbose error message according to the given config.
    52  func encodeError(key string, err error, enc FieldEncoder, c ErrorEncoderConfig) {
    53  	var msg string
    54  	if err == nil {
    55  		msg = "<nil>"
    56  	} else {
    57  		msg = err.Error()
    58  	}
    59  	enc.EncodeFieldString(key, msg)
    60  
    61  	if !c.NoVerboseField {
    62  		switch err.(type) {
    63  		case fmt.Formatter:
    64  			verbose := fmt.Sprintf("%+v", err)
    65  			if verbose != msg {
    66  				enc.EncodeFieldString(key+c.VerboseFieldSuffix, verbose)
    67  			}
    68  		}
    69  	}
    70  }