| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182 |
- // Copyright (c) Tailscale Inc & AUTHORS
- // SPDX-License-Identifier: BSD-3-Clause
- // Package vizerror provides types and utility funcs for handling visible errors
- // that are safe to display to end users.
- package vizerror
- import (
- "errors"
- "fmt"
- )
- // Error is an error that is safe to display to end users.
- type Error struct {
- publicErr error // visible to end users
- wrapped error // internal
- }
- // Error implements the error interface. The returned string is safe to display
- // to end users.
- func (e Error) Error() string {
- return e.publicErr.Error()
- }
- // New returns an error that formats as the given text. It always returns a vizerror.Error.
- func New(publicMsg string) error {
- err := errors.New(publicMsg)
- return Error{
- publicErr: err,
- wrapped: err,
- }
- }
- // Errorf returns an Error with 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 Errorf(publicMsgFormat string, a ...any) error {
- err := fmt.Errorf(publicMsgFormat, a...)
- return Error{
- publicErr: err,
- wrapped: err,
- }
- }
- // Unwrap returns the underlying error.
- //
- // If the Error was constructed using [WrapWithMessage], this is the wrapped (internal) error
- // and not the user-visible error message.
- func (e Error) Unwrap() error {
- return e.wrapped
- }
- // Wrap wraps publicErr with a vizerror.Error.
- //
- // Deprecated: this is almost always the wrong thing to do. Are you really sure
- // you know exactly what err.Error() will stringify to and be safe to show to
- // users? [WrapWithMessage] is probably what you want.
- func Wrap(publicErr error) error {
- if publicErr == nil {
- return nil
- }
- return Error{publicErr: publicErr, wrapped: publicErr}
- }
- // WrapWithMessage wraps the given error with a message that's safe to display
- // to end users. The text of the wrapped error will not be displayed to end
- // users.
- //
- // WrapWithMessage should almost always be preferred to [Wrap].
- func WrapWithMessage(wrapped error, publicMsg string) error {
- return Error{
- publicErr: errors.New(publicMsg),
- 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)
- return
- }
|