Skip to content

Commit

Permalink
First steps reducing fmt usage.
Browse files Browse the repository at this point in the history
Per capnproto#364, this is a first step on the road to eliminating usage of fmt
from the library; it removes most direct uses of it from the exc
package. The remaining bits are Failedf and friends. I'd like to just
remove these, but that requires changing every downstream call site, and
I wanted to keep this patch small for today; I can tackle that when I
have a bit more time. I don't think it will be too hard; from a quick
skim WrapError covers 99% of the use cases, and the rest won't be hard
to replace with things from strconv.
  • Loading branch information
zenhack committed Dec 4, 2022
1 parent 6f24fa5 commit 21bb5f7
Showing 1 changed file with 32 additions and 8 deletions.
40 changes: 32 additions & 8 deletions exc/exc.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ package exc
import (
"errors"
"fmt"
"strconv"
)

// Exception is an error that designates a Cap'n Proto exception.
Expand All @@ -13,6 +14,26 @@ type Exception struct {
Cause error
}

type wrappedError struct {
prefix string
base error
}

func (e wrappedError) Error() string {
return e.prefix + ": " + e.base.Error()
}

func (e wrappedError) Unwrap() error {
return e.base
}

func WrapError(prefix string, err error) error {
return wrappedError{
prefix: prefix,
base: err,
}
}

// New creates a new error that formats as "<prefix>: <msg>".
// The type can be recovered using the TypeOf() function.
func New(typ Type, prefix, msg string) *Exception {
Expand All @@ -24,27 +45,30 @@ func (e Exception) Error() string {
return e.Cause.Error()
}

return fmt.Sprintf("%s: %v", e.Prefix, e.Cause)
return WrapError(e.Prefix, e.Cause).Error()
}

func (e Exception) Unwrap() error { return e.Cause }

func (e Exception) GoString() string {
return fmt.Sprintf("errors.Error{Type: %s, Prefix: %q, Cause: fmt.Errorf(%q)}",
e.Type.GoString(),
e.Prefix,
e.Cause)
return "errors.Error{Type: " +
e.Type.GoString() +
", Prefix: " +
strconv.Quote(e.Prefix) +
", Cause: " +
strconv.Quote(e.Cause.Error()) +
"}"
}

// Annotate is creates a new error that formats as "<prefix>: <msg>: <e>".
// If e.Prefix == prefix, the prefix will not be duplicated.
// The returned Error.Type == e.Type.
func (e Exception) Annotate(prefix, msg string) *Exception {
if prefix != e.Prefix {
return &Exception{e.Type, prefix, fmt.Errorf("%s: %w", msg, e)}
return &Exception{e.Type, prefix, WrapError(msg, e)}
}

return &Exception{e.Type, prefix, fmt.Errorf("%s: %w", msg, e.Cause)}
return &Exception{e.Type, prefix, WrapError(msg, e.Cause)}
}

// Annotate creates a new error that formats as "<prefix>: <msg>: <err>".
Expand All @@ -62,7 +86,7 @@ func Annotate(prefix, msg string, err error) *Exception {
return &Exception{
Type: Failed,
Prefix: prefix,
Cause: fmt.Errorf("%s: %w", msg, err),
Cause: WrapError(msg, err),
}
}

Expand Down

0 comments on commit 21bb5f7

Please sign in to comment.