@@ -73,6 +73,89 @@ func IsCommonError(target error) bool {
7373 return Any (target , ErrNotImplemented , ErrNoExtension , ErrNoLogger , ErrNoLoggerSource , ErrNoLogSource , ErrUndefined , ErrInvalidDestination , ErrTimeout , ErrLocked , ErrStaleLock , ErrExists , ErrNotFound , ErrUnsupported , ErrUnavailable , ErrWrongUser , ErrUnauthorised , ErrUnknown , ErrInvalid , ErrConflict , ErrMarshalling , ErrCancelled , ErrEmpty , ErrUnexpected , ErrTooLarge , ErrForbidden , ErrCondition , ErrEOF , ErrMalicious , ErrWarning , ErrOutOfRange , ErrFailed )
7474}
7575
76+ // RetrieveCommonError tries to return the common error of an error.
77+ func RetrieveCommonError (target error ) (isCommonError bool , commonError error ) {
78+ switch {
79+ case IsEmpty (target ):
80+ return true , nil
81+ case Any (target , ErrNotImplemented ):
82+ return true , ErrNotImplemented
83+ case Any (target , ErrNoExtension ):
84+ return true , ErrNoExtension
85+ case Any (target , ErrNoLogger ):
86+ return true , ErrNoLogger
87+ case Any (target , ErrNoLoggerSource ):
88+ return true , ErrNoLoggerSource
89+ case Any (target , ErrNoLogSource ):
90+ return true , ErrNoLogSource
91+ case Any (target , ErrUndefined ):
92+ return true , ErrUndefined
93+ case Any (target , ErrInvalidDestination ):
94+ return true , ErrInvalidDestination
95+ case Any (target , ErrTimeout ):
96+ return true , ErrTimeout
97+ case Any (target , ErrLocked ):
98+ return true , ErrLocked
99+ case Any (target , ErrStaleLock ):
100+ return true , ErrStaleLock
101+ case Any (target , ErrExists ):
102+ return true , ErrExists
103+ case Any (target , ErrNotFound ):
104+ return true , ErrNotFound
105+ case Any (target , ErrUnsupported ):
106+ return true , ErrUnsupported
107+ case Any (target , ErrUnavailable ):
108+ return true , ErrUnavailable
109+ case Any (target , ErrWrongUser ):
110+ return true , ErrWrongUser
111+ case Any (target , ErrUnauthorised ):
112+ return true , ErrUnauthorised
113+ case Any (target , ErrUnknown ):
114+ return true , ErrUnknown
115+ case Any (target , ErrInvalid ):
116+ return true , ErrInvalid
117+ case Any (target , ErrConflict ):
118+ return true , ErrConflict
119+ case Any (target , ErrMarshalling ):
120+ return true , ErrMarshalling
121+ case Any (target , ErrCancelled ):
122+ return true , ErrCancelled
123+ case Any (target , ErrEmpty ):
124+ return true , ErrEmpty
125+ case Any (target , ErrUnexpected ):
126+ return true , ErrUnexpected
127+ case Any (target , ErrTooLarge ):
128+ return true , ErrTooLarge
129+ case Any (target , ErrForbidden ):
130+ return true , ErrForbidden
131+ case Any (target , ErrCondition ):
132+ return true , ErrCondition
133+ case Any (target , ErrEOF ):
134+ return true , ErrEOF
135+ case Any (target , ErrMalicious ):
136+ return true , ErrMalicious
137+ case Any (target , ErrOutOfRange ):
138+ return true , ErrOutOfRange
139+ case Any (target , ErrFailed ):
140+ return true , ErrFailed
141+ case Any (target , ErrWarning ):
142+ return true , ErrWarning
143+ }
144+
145+ underlyingErr , parseError := GetUnderlyingErrorType (target )
146+ if parseError != nil {
147+ commonError = ErrUnknown
148+ return
149+ }
150+ if IsCommonError (underlyingErr ) {
151+ commonError = underlyingErr
152+ isCommonError = true
153+ } else {
154+ commonError = ErrUnknown
155+ }
156+ return
157+ }
158+
76159// Any determines whether the target error is of the same type as any of the errors `err`
77160func Any (target error , err ... error ) bool {
78161 for i := range err {
@@ -371,6 +454,36 @@ func Errorf(targetErr error, format string, args ...any) error {
371454 }
372455}
373456
457+ // DescribeCircumstance adds some context to a particular error. If the error is of a known type (as in, a common error), it will be kept. Otherwise, it will be set as Unexpected.
458+ func DescribeCircumstance (originalError error , circumstance string ) error {
459+ origErr := ConvertContextError (originalError )
460+ isCommonError , commonError := RetrieveCommonError (origErr )
461+ if isCommonError {
462+ return WrapError (commonError , origErr , circumstance )
463+ }
464+ return WrapError (ErrUnexpected , origErr , circumstance )
465+ }
466+
467+ // DescribeCircumstanceAndKeepType does almost the same as DescribeCircumstance but if the err is not a common error, it won't wrap it but just add the context string to it.
468+ func DescribeCircumstanceAndKeepType (err error , circumstance string ) error {
469+ origErr := ConvertContextError (err )
470+ isCommonError , commonError := RetrieveCommonError (origErr )
471+ if isCommonError {
472+ return WrapError (commonError , origErr , circumstance )
473+ }
474+ return New (origErr , circumstance )
475+ }
476+
477+ // DescribeCircumstanceAndKeepTypef is like DescribeCircumstanceAndKeepType but uses a message format to describe the error context.
478+ func DescribeCircumstanceAndKeepTypef (err error , circumstanceFormat string , args ... any ) error {
479+ return DescribeCircumstanceAndKeepType (err , fmt .Sprintf (circumstanceFormat , args ... ))
480+ }
481+
482+ // DescribeCircumstancef is the same as DescribeCircumstance but uses a format for capturing the error context.
483+ func DescribeCircumstancef (err error , circumstanceFormat string , args ... any ) error {
484+ return DescribeCircumstance (err , fmt .Sprintf (circumstanceFormat , args ... ))
485+ }
486+
374487// WrapError wraps an error into a particular targetError. However, if the original error has to do with a contextual error (i.e. ErrCancelled or ErrTimeout) or should be considered as a failure rather than an error, it will be passed through without having its type changed.
375488// Same is true with warnings.
376489// This method should be used to safely wrap errors without losing information about context control information.
@@ -407,7 +520,7 @@ func WrapIfNotCommonError(targetError, originalError error, msg string) error {
407520 return WrapError (targetError , originalError , msg )
408521 }
409522 if IsCommonError (originalError ) {
410- return New (originalError , msg )
523+ return DescribeCircumstance (originalError , msg )
411524 }
412525 return WrapError (targetError , originalError , msg )
413526}
@@ -426,7 +539,7 @@ func WrapIfNotCommonErrorf(targetError, originalError error, msgFormat string, a
426539 return WrapErrorf (targetError , originalError , msgFormat , args ... )
427540 }
428541 if IsCommonError (originalError ) {
429- return Newf (originalError , msgFormat , args ... )
542+ return DescribeCircumstancef (originalError , msgFormat , args ... )
430543 }
431544 return WrapErrorf (targetError , originalError , msgFormat , args ... )
432545}
0 commit comments