github.com/observiq/carbon@v0.9.11-0.20200820160507-1b872e368a5e/errors/error.go (about)

     1  package errors
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  
     7  	"go.uber.org/zap/zapcore"
     8  )
     9  
    10  // AgentError is an error that occurs in the agent.
    11  type AgentError struct {
    12  	Description string
    13  	Suggestion  string
    14  	Details     ErrorDetails
    15  }
    16  
    17  // Error will return the error message.
    18  func (e AgentError) Error() string {
    19  	if len(e.Details) == 0 {
    20  		return e.Description
    21  	}
    22  	marshalled, _ := json.Marshal(e.Details)
    23  	return fmt.Sprintf("%s: %s", e.Description, string(marshalled))
    24  }
    25  
    26  // MarshalLogObject will define the representation of this error when logging.
    27  func (e AgentError) MarshalLogObject(encoder zapcore.ObjectEncoder) error {
    28  	encoder.AddString("description", e.Description)
    29  
    30  	if e.Suggestion != "" {
    31  		encoder.AddString("suggestion", e.Suggestion)
    32  	}
    33  
    34  	if len(e.Details) != 0 {
    35  		err := encoder.AddObject("details", e.Details)
    36  		if err != nil {
    37  			return err
    38  		}
    39  	}
    40  
    41  	return nil
    42  }
    43  
    44  // WithDetails will return the error with additional details
    45  func (e AgentError) WithDetails(keyValues ...string) AgentError {
    46  	return WithDetails(e, keyValues...)
    47  }
    48  
    49  // WithDetails will add details to an agent error
    50  func WithDetails(err error, keyValues ...string) AgentError {
    51  	if agentErr, ok := err.(AgentError); ok {
    52  		if len(keyValues) > 0 {
    53  			for i := 0; i+1 < len(keyValues); i += 2 {
    54  				agentErr.Details[keyValues[i]] = keyValues[i+1]
    55  			}
    56  		}
    57  		return agentErr
    58  	}
    59  	return NewError(err.Error(), "", keyValues...)
    60  }
    61  
    62  // Wrap adds context to the description for richer logs
    63  func Wrap(err error, context string) AgentError {
    64  	if agentErr, ok := err.(AgentError); ok {
    65  		agentErr.Description = fmt.Sprintf("%s: %s", context, agentErr.Description)
    66  		return agentErr
    67  	}
    68  
    69  	return NewError(fmt.Sprintf("%s: %s", context, err.Error()), "")
    70  }
    71  
    72  // NewError will create a new agent error.
    73  func NewError(description string, suggestion string, keyValues ...string) AgentError {
    74  	return AgentError{
    75  		Description: description,
    76  		Suggestion:  suggestion,
    77  		Details:     createDetails(keyValues),
    78  	}
    79  }