util/vizerror: add Wrapf function that combines Errorf with Wrap

This makes it convenient to wrap an error with a vizerror that needs to use a format string.

Updates tailscale/corp#27066

Signed-off-by: Percy Wegmann <percy@tailscale.com>
This commit is contained in:
Percy Wegmann 2025-03-14 09:02:36 -05:00
parent 8b1e7f646e
commit 414b5b8402
No known key found for this signature in database
GPG Key ID: 29D8CDEB4C13D48B
2 changed files with 23 additions and 0 deletions

View File

@ -75,6 +75,18 @@ func WrapWithMessage(wrapped error, publicMsg string) error {
}
}
// Wrapf wraps the given error with a Vizerror built using the specified publicMsgFormat and values.
// It always returns a vizerror.Error.
//
// Warning: avoid using an error as one of the format arguments, as this will cause the text
// of that error to be displayed to the end user (which is probably not what you want).
func Wrapf(wrapped error, publicMsgFormat string, a ...any) error {
return Error{
publicErr: fmt.Errorf(publicMsgFormat, a...),
wrapped: wrapped,
}
}
// As returns the first vizerror.Error in err's chain.
func As(err error) (e Error, ok bool) {
ok = errors.As(err, &e)

View File

@ -64,3 +64,14 @@ func TestWrapWithMessage(t *testing.T) {
t.Errorf("Unwrap = %q, want %q", errors.Unwrap(err), wrapped)
}
}
func TestWrapf(t *testing.T) {
wrapped := errors.New("wrapped")
err := Wrapf(wrapped, "safe: %s", "for sure")
if err.Error() != "safe: for sure" {
t.Errorf(`Wrapf(wrapped, "safe: for sure").Error() = %q, want %q`, err.Error(), "safe: for sure")
}
if errors.Unwrap(err) != wrapped {
t.Errorf("Unwrap = %q, want %q", errors.Unwrap(err), wrapped)
}
}