Error returns a redacted error that wraps err. If err has a Redact() string method, then Error uses it for the redacted error message. Otherwise, Error recursively redacts each wrapped error, joining them with ": " to create the final error message. If it encounters an error that has a Redact() meth
(err error)
| 70 | // final error message. If it encounters an error that has a Redact() method, |
| 71 | // then it appends the result of Redact() to the message and stops unwrapping. |
| 72 | func Error(err error) error { |
| 73 | if err == nil { |
| 74 | return nil |
| 75 | } |
| 76 | |
| 77 | switch t := err.(type) { |
| 78 | case *redactedError: |
| 79 | // Don't redact an already redacted error, otherwise its redacted message |
| 80 | // will be replaced with a placeholder. |
| 81 | return err |
| 82 | case redactor: |
| 83 | return &redactedError{ |
| 84 | msg: t.Redact(), |
| 85 | wrapped: err, |
| 86 | } |
| 87 | default: |
| 88 | msg := placeholder(err) |
| 89 | wrapped := err |
| 90 | for { |
| 91 | wrapped = errors.Unwrap(wrapped) |
| 92 | if wrapped == nil { |
| 93 | break |
| 94 | } |
| 95 | if redactor, ok := wrapped.(redactor); ok { |
| 96 | msg += ": " + redactor.Redact() |
| 97 | break |
| 98 | } |
| 99 | msg += ": " + placeholder(wrapped) |
| 100 | } |
| 101 | return &redactedError{ |
| 102 | msg: msg, |
| 103 | wrapped: err, |
| 104 | } |
| 105 | } |
| 106 | } |
| 107 | |
| 108 | // Errorf creates a redactable error that has an error string identical to that |
| 109 | // of a [fmt.Errorf] error. Calling [Redact] on the result will redact all |