github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/vendor_skip/go.mongodb.org/mongo-driver/internal/error.go (about)

     1  // Copyright (C) MongoDB, Inc. 2017-present.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
     4  // not use this file except in compliance with the License. You may obtain
     5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
     6  
     7  package internal
     8  
     9  import (
    10  	"fmt"
    11  )
    12  
    13  // WrappedError represents an error that contains another error.
    14  type WrappedError interface {
    15  	// Message gets the basic message of the error.
    16  	Message() string
    17  	// Inner gets the inner error if one exists.
    18  	Inner() error
    19  }
    20  
    21  // RolledUpErrorMessage gets a flattened error message.
    22  func RolledUpErrorMessage(err error) string {
    23  	if wrappedErr, ok := err.(WrappedError); ok {
    24  		inner := wrappedErr.Inner()
    25  		if inner != nil {
    26  			return fmt.Sprintf("%s: %s", wrappedErr.Message(), RolledUpErrorMessage(inner))
    27  		}
    28  
    29  		return wrappedErr.Message()
    30  	}
    31  
    32  	return err.Error()
    33  }
    34  
    35  // UnwrapError attempts to unwrap the error down to its root cause.
    36  func UnwrapError(err error) error {
    37  
    38  	switch tErr := err.(type) {
    39  	case WrappedError:
    40  		return UnwrapError(tErr.Inner())
    41  	case *multiError:
    42  		return UnwrapError(tErr.errors[0])
    43  	}
    44  
    45  	return err
    46  }
    47  
    48  // WrapError wraps an error with a message.
    49  func WrapError(inner error, message string) error {
    50  	return &wrappedError{message, inner}
    51  }
    52  
    53  // WrapErrorf wraps an error with a message.
    54  func WrapErrorf(inner error, format string, args ...interface{}) error {
    55  	return &wrappedError{fmt.Sprintf(format, args...), inner}
    56  }
    57  
    58  // MultiError combines multiple errors into a single error. If there are no errors,
    59  // nil is returned. If there is 1 error, it is returned. Otherwise, they are combined.
    60  func MultiError(errors ...error) error {
    61  
    62  	// remove nils from the error list
    63  	var nonNils []error
    64  	for _, e := range errors {
    65  		if e != nil {
    66  			nonNils = append(nonNils, e)
    67  		}
    68  	}
    69  
    70  	switch len(nonNils) {
    71  	case 0:
    72  		return nil
    73  	case 1:
    74  		return nonNils[0]
    75  	default:
    76  		return &multiError{
    77  			message: "multiple errors encountered",
    78  			errors:  nonNils,
    79  		}
    80  	}
    81  }
    82  
    83  type multiError struct {
    84  	message string
    85  	errors  []error
    86  }
    87  
    88  func (e *multiError) Message() string {
    89  	return e.message
    90  }
    91  
    92  func (e *multiError) Error() string {
    93  	result := e.message
    94  	for _, e := range e.errors {
    95  		result += fmt.Sprintf("\n  %s", e)
    96  	}
    97  	return result
    98  }
    99  
   100  func (e *multiError) Errors() []error {
   101  	return e.errors
   102  }
   103  
   104  type wrappedError struct {
   105  	message string
   106  	inner   error
   107  }
   108  
   109  func (e *wrappedError) Message() string {
   110  	return e.message
   111  }
   112  
   113  func (e *wrappedError) Error() string {
   114  	return RolledUpErrorMessage(e)
   115  }
   116  
   117  func (e *wrappedError) Inner() error {
   118  	return e.inner
   119  }
   120  
   121  func (e *wrappedError) Unwrap() error {
   122  	return e.inner
   123  }