github.com/alloyzeus/go-azfl@v0.0.0-20231220071816-9740126a2d07/errors/operation.go (about)

     1  package errors
     2  
     3  // Something that has more semantic than "Wrap"
     4  // See https://github.com/alloyzeus/go-azfl/issues/8 for the discussions on
     5  // what we want to implement.
     6  
     7  type OperationError interface {
     8  	Unwrappable
     9  
    10  	// Returns the name of the operation.
    11  	OperationName() string
    12  }
    13  
    14  type OperationErrorBuilder interface {
    15  	OperationError
    16  
    17  	// Hint provides a clue for the developers on how to fix the error.
    18  	Hint(hintText string) OperationErrorBuilder
    19  
    20  	Params(params ...NamedError) OperationErrorBuilder
    21  
    22  	// Wrap returns a copy with wrapped error is set to detailingError.
    23  	Wrap(detailingError error) OperationErrorBuilder
    24  }
    25  
    26  func Op(operationName string) OperationErrorBuilder {
    27  	return &opError{operationName: operationName}
    28  }
    29  
    30  type opError struct {
    31  	operationName string
    32  	hintText      string
    33  	params        []NamedError
    34  	wrapped       error
    35  }
    36  
    37  var (
    38  	_ error                 = &opError{}
    39  	_ Unwrappable           = &opError{}
    40  	_ OperationError        = &opError{}
    41  	_ OperationErrorBuilder = &opError{}
    42  )
    43  
    44  func (e opError) OperationName() string { return e.operationName }
    45  
    46  func (e opError) Unwrap() error { return e.wrapped }
    47  
    48  func (e *opError) Error() string {
    49  	suffix := namedSetToString(e.params)
    50  	if suffix != "" {
    51  		suffix = ". " + suffix
    52  	}
    53  	if e.hintText != "" {
    54  		suffix = suffix + ". " + e.hintText
    55  	}
    56  	var descStr string
    57  	causeStr := errorString(e.wrapped)
    58  	if causeStr == "" {
    59  		causeStr = descStr
    60  	} else if descStr != "" {
    61  		causeStr = descStr + ": " + causeStr
    62  	}
    63  
    64  	if e.operationName != "" {
    65  		if causeStr != "" {
    66  			return e.operationName + ": " + causeStr + suffix
    67  		}
    68  		if suffix != "" {
    69  			return e.operationName + " error" + suffix
    70  		}
    71  		return e.operationName + " error"
    72  	}
    73  	if causeStr != "" {
    74  		return "operation " + causeStr + suffix
    75  	}
    76  	if suffix != "" {
    77  		return "operation error" + suffix
    78  	}
    79  	return "operation error"
    80  }
    81  
    82  func (e opError) Hint(hintText string) OperationErrorBuilder {
    83  	e.hintText = hintText
    84  	return &e
    85  }
    86  
    87  func (e opError) Params(params ...NamedError) OperationErrorBuilder {
    88  	e.params = copyNamedSet(params)
    89  	return &e
    90  }
    91  
    92  func (e opError) Wrap(detailingError error) OperationErrorBuilder {
    93  	e.wrapped = detailingError
    94  	return &e
    95  }