Documentation ¶
Overview ¶
Package redact implements functions to redact sensitive information from errors.
Redacting an error replaces its message with a placeholder while still maintaining wrapped errors:
wrapped := errors.New("not found") name := "Alex" err := fmt.Errorf("error getting user %s: %w", name, wrapped) fmt.Println(err) // error getting user Alex: not found fmt.Println(Error(err)) // <redacted *fmt.wrapError>: <redacted *errors.errorString>
If an error implements a Redact() string method, then it is said to be redactable. A redactable error defines an alternative message for its redacted form:
type userErr struct{ name string } func (e *userErr) Error() string { return fmt.Sprintf("user %s not found", e.name) } func (e *userErr) Redact() string { return fmt.Sprintf("user %x not found", sha256.Sum256([]byte(e.name))) } func main() { err := &userErr{name: "Alex"} fmt.Println(err) // user Alex not found fmt.Println(Error(err)) // user db74c940d447e877d119df613edd2700c4a84cd1cf08beb7cbc319bcfaeab97a not found }
The Errorf function creates redactable errors that retain their literal format text, but redact any arguments. The format string spec is identical to that of fmt.Errorf. Calling Safe on an Errorf argument will include it in the redacted message.
name := "Alex" id := 5 err := Errorf("error getting user %s with ID %d", name, Safe(id)) fmt.Println(err) // error getting user Alex with ID 5 fmt.Println(Error(err)) // error getting user <redacted string> with ID 5
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Error ¶
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() method, then it appends the result of Redact() to the message and stops unwrapping.
Example ¶
// Each error string in a chain of wrapped errors is redacted with a // placeholder describing the error's type. wrapped := errors.New("not found") name := "Alex" err := fmt.Errorf("error getting user %s: %w", name, wrapped) fmt.Println("Normal:", err) fmt.Println("Redacted:", Error(err))
Output: Normal: error getting user Alex: not found Redacted: <redacted *fmt.wrapError>: <redacted *errors.errorString>
Example (Wrapped) ¶
// If an error wraps another, then redacting it results in a message with the // redacted version of each error in the chain up until the first redactable // error. name := "Alex" err := fmt.Errorf("fatal error: %w", Errorf("error getting user %s: %w", name, errors.New("not found"))) fmt.Println("Normal:", err) fmt.Println("Redacted:", Error(err))
Output: Normal: fatal error: error getting user Alex: not found Redacted: <redacted *fmt.wrapError>: error getting user <redacted string>: <redacted *errors.errorString>
func Errorf ¶
Errorf creates a redactable error that has an error string identical to that of a fmt.Errorf error. Calling [Redact] on the result will redact all format arguments from the error message instead of redacting the entire string.
When redacting the error string, Errorf replaces arguments that implement a Redact() string method with the result of that method. To include an argument as-is in the redacted error, first call Safe. For example:
username := "bob" Errorf("cannot find user %s", username).Error() // cannot find user <redacted string> Errorf("cannot find user %s", Safe(username)).Error() // cannot find user bob
Example ¶
// Errors created with Errorf are redacted by omitting any arguments not // marked as safe. The literal portion of the format string is kept. wrapped := errors.New("not found") name := "Alex" id := 5 err := Errorf("error getting user %s with ID %d: %w", name, Safe(id), wrapped) fmt.Println("Normal:", err) fmt.Println("Redacted:", Error(err))
Output: Normal: error getting user Alex with ID 5: not found Redacted: error getting user <redacted string> with ID 5: <redacted *errors.errorString>
Types ¶
This section is empty.