[WIP] Initial commit
This commit is contained in:
74
vendor/github.com/cockroachdb/errors/errutil/as.go
generated
vendored
Normal file
74
vendor/github.com/cockroachdb/errors/errutil/as.go
generated
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Copyright 2019 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errutil
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/cockroachdb/errors/errbase"
|
||||
)
|
||||
|
||||
// As finds the first error in err's chain that matches the type to which target
|
||||
// points, and if so, sets the target to its value and returns true. An error
|
||||
// matches a type if it is assignable to the target type, or if it has a method
|
||||
// As(interface{}) bool such that As(target) returns true. As will panic if target
|
||||
// is not a non-nil pointer to a type which implements error or is of interface type.
|
||||
//
|
||||
// The As method should set the target to its value and return true if err
|
||||
// matches the type to which target points.
|
||||
//
|
||||
// Note: this implementation differs from that of xerrors as follows:
|
||||
// - it also supports recursing through causes with Cause().
|
||||
// - if it detects an API use error, its panic object is a valid error.
|
||||
func As(err error, target interface{}) bool {
|
||||
if target == nil {
|
||||
panic(AssertionFailedf("errors.As: target cannot be nil"))
|
||||
}
|
||||
|
||||
// We use introspection for now, of course when/if Go gets generics
|
||||
// all this can go away.
|
||||
val := reflect.ValueOf(target)
|
||||
typ := val.Type()
|
||||
if typ.Kind() != reflect.Ptr || val.IsNil() {
|
||||
panic(AssertionFailedf("errors.As: target must be a non-nil pointer, found %T", target))
|
||||
}
|
||||
if e := typ.Elem(); e.Kind() != reflect.Interface && !e.Implements(errorType) {
|
||||
panic(AssertionFailedf("errors.As: *target must be interface or implement error, found %T", target))
|
||||
}
|
||||
|
||||
targetType := typ.Elem()
|
||||
for c := err; c != nil; c = errbase.UnwrapOnce(c) {
|
||||
if reflect.TypeOf(c).AssignableTo(targetType) {
|
||||
val.Elem().Set(reflect.ValueOf(c))
|
||||
return true
|
||||
}
|
||||
if x, ok := c.(interface{ As(interface{}) bool }); ok && x.As(target) {
|
||||
return true
|
||||
}
|
||||
|
||||
// If at any point in the single cause chain including the top,
|
||||
// we encounter a multi-cause chain, recursively explore it.
|
||||
for _, cause := range errbase.UnwrapMulti(c) {
|
||||
if As(cause, target) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
var errorType = reflect.TypeOf((*error)(nil)).Elem()
|
||||
80
vendor/github.com/cockroachdb/errors/errutil/assertions.go
generated
vendored
Normal file
80
vendor/github.com/cockroachdb/errors/errutil/assertions.go
generated
vendored
Normal file
@@ -0,0 +1,80 @@
|
||||
// Copyright 2019 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errutil
|
||||
|
||||
import (
|
||||
"github.com/cockroachdb/errors/assert"
|
||||
"github.com/cockroachdb/errors/barriers"
|
||||
"github.com/cockroachdb/errors/withstack"
|
||||
)
|
||||
|
||||
// AssertionFailedf creates an internal error.
|
||||
//
|
||||
// Detail is shown:
|
||||
// - via `errors.GetSafeDetails()`, shows redacted strings.
|
||||
// - when formatting with `%+v`.
|
||||
// - in Sentry reports.
|
||||
func AssertionFailedf(format string, args ...interface{}) error {
|
||||
return AssertionFailedWithDepthf(1, format, args...)
|
||||
}
|
||||
|
||||
// AssertionFailedWithDepthf creates an internal error
|
||||
// with a stack trace collected at the specified depth.
|
||||
// See the doc of `AssertionFailedf()` for more details.
|
||||
func AssertionFailedWithDepthf(depth int, format string, args ...interface{}) error {
|
||||
err := NewWithDepthf(1+depth, format, args...)
|
||||
err = assert.WithAssertionFailure(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// HandleAsAssertionFailure hides an error and turns it into
|
||||
// an assertion failure. Both details from the original error and the
|
||||
// context of the caller are preserved. The original error is not
|
||||
// visible as cause any more. The original error message is preserved.
|
||||
// See the doc of `AssertionFailedf()` for more details.
|
||||
func HandleAsAssertionFailure(origErr error) error {
|
||||
return HandleAsAssertionFailureDepth(1, origErr)
|
||||
}
|
||||
|
||||
// HandleAsAssertionFailureDepth is like HandleAsAssertionFailure but
|
||||
// the depth at which the call stack is captured can be specified.
|
||||
func HandleAsAssertionFailureDepth(depth int, origErr error) error {
|
||||
err := barriers.Handled(origErr)
|
||||
err = withstack.WithStackDepth(err, 1+depth)
|
||||
err = assert.WithAssertionFailure(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// NewAssertionErrorWithWrappedErrf wraps an error and turns it into
|
||||
// an assertion error. Both details from the original error and the
|
||||
// context of the caller are preserved. The original error is not
|
||||
// visible as cause any more. The original error message is preserved.
|
||||
// See the doc of `AssertionFailedf()` for more details.
|
||||
func NewAssertionErrorWithWrappedErrf(origErr error, format string, args ...interface{}) error {
|
||||
return NewAssertionErrorWithWrappedErrDepthf(1, origErr, format, args...)
|
||||
}
|
||||
|
||||
// NewAssertionErrorWithWrappedErrDepthf is like
|
||||
// NewAssertionErrorWithWrappedErrf but the depth at which the call
|
||||
// stack is captured can be specified.
|
||||
// See the doc of `AssertionFailedf()` for more details.
|
||||
func NewAssertionErrorWithWrappedErrDepthf(
|
||||
depth int, origErr error, format string, args ...interface{},
|
||||
) error {
|
||||
err := barriers.Handled(origErr)
|
||||
err = WrapWithDepthf(depth+1, err, format, args...)
|
||||
err = assert.WithAssertionFailure(err)
|
||||
return err
|
||||
}
|
||||
19
vendor/github.com/cockroachdb/errors/errutil/doc.go
generated
vendored
Normal file
19
vendor/github.com/cockroachdb/errors/errutil/doc.go
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// Copyright 2019 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
// Package errutil combines primitives from the library, the Go errors
|
||||
// package and github.com/pkg/errors. It aims to serve as drop-in
|
||||
// replacement to gitub.com/pkg/errors and replace the legacy
|
||||
// implementation of `pgerrors`.
|
||||
package errutil
|
||||
88
vendor/github.com/cockroachdb/errors/errutil/format_error_special.go
generated
vendored
Normal file
88
vendor/github.com/cockroachdb/errors/errutil/format_error_special.go
generated
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2020 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net"
|
||||
"os"
|
||||
"runtime"
|
||||
"syscall"
|
||||
|
||||
"github.com/cockroachdb/errors/errbase"
|
||||
"github.com/cockroachdb/errors/markers"
|
||||
"github.com/cockroachdb/redact"
|
||||
)
|
||||
|
||||
func init() {
|
||||
errbase.RegisterSpecialCasePrinter(specialCaseFormat)
|
||||
}
|
||||
|
||||
func specialCaseFormat(err error, p errbase.Printer, isLeaf bool) (handled bool, next error) {
|
||||
if isLeaf && markers.IsAny(err,
|
||||
context.DeadlineExceeded,
|
||||
context.Canceled,
|
||||
os.ErrInvalid,
|
||||
os.ErrPermission,
|
||||
os.ErrExist,
|
||||
os.ErrNotExist,
|
||||
os.ErrClosed,
|
||||
os.ErrNoDeadline) {
|
||||
p.Print(redact.Safe(err.Error()))
|
||||
return true, nil
|
||||
}
|
||||
|
||||
switch v := err.(type) {
|
||||
// The following two types are safe too.
|
||||
case runtime.Error:
|
||||
p.Print(redact.Safe(v.Error()))
|
||||
return true, err
|
||||
case syscall.Errno:
|
||||
p.Print(redact.Safe(v.Error()))
|
||||
return true, err
|
||||
case *os.SyscallError:
|
||||
p.Print(redact.Safe(v.Syscall))
|
||||
return true, err
|
||||
case *os.PathError:
|
||||
p.Printf("%s %s", redact.Safe(v.Op), v.Path)
|
||||
return true, err
|
||||
case *os.LinkError:
|
||||
p.Printf("%s %s %s", redact.Safe(v.Op), v.Old, v.New)
|
||||
return true, err
|
||||
case *net.OpError:
|
||||
p.Print(redact.Safe(v.Op))
|
||||
if v.Net != "" {
|
||||
p.Printf(" %s", redact.Safe(v.Net))
|
||||
}
|
||||
if v.Source != nil {
|
||||
p.Printf(" %s", v.Source)
|
||||
}
|
||||
if v.Addr != nil {
|
||||
if v.Source != nil {
|
||||
p.Printf(" ->")
|
||||
}
|
||||
p.Printf(" %s", v.Addr)
|
||||
}
|
||||
return true, err
|
||||
case redact.SafeMessager:
|
||||
// Backward-compatibility with previous versions
|
||||
// of the errors library: if an error type implements
|
||||
// SafeMessage(), use that instead of its error message.
|
||||
p.Print(redact.Safe(v.SafeMessage()))
|
||||
// It also short-cuts any further causes.
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
45
vendor/github.com/cockroachdb/errors/errutil/message.go
generated
vendored
Normal file
45
vendor/github.com/cockroachdb/errors/errutil/message.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
// Copyright 2019 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errutil
|
||||
|
||||
import "github.com/cockroachdb/redact"
|
||||
|
||||
// WithMessage annotates err with a new message.
|
||||
// If err is nil, WithMessage returns nil.
|
||||
// The message is considered safe for reporting
|
||||
// and is included in Sentry reports.
|
||||
func WithMessage(err error, message string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &withPrefix{
|
||||
cause: err,
|
||||
prefix: redact.Sprint(redact.Safe(message)),
|
||||
}
|
||||
}
|
||||
|
||||
// WithMessagef annotates err with the format specifier.
|
||||
// If err is nil, WithMessagef returns nil.
|
||||
// The message is formatted as per redact.Sprintf,
|
||||
// to separate safe and unsafe strings for Sentry reporting.
|
||||
func WithMessagef(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &withPrefix{
|
||||
cause: err,
|
||||
prefix: redact.Sprintf(format, args...),
|
||||
}
|
||||
}
|
||||
163
vendor/github.com/cockroachdb/errors/errutil/redactable.go
generated
vendored
Normal file
163
vendor/github.com/cockroachdb/errors/errutil/redactable.go
generated
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
package errutil
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cockroachdb/errors/errbase"
|
||||
"github.com/cockroachdb/errors/errorspb"
|
||||
"github.com/cockroachdb/redact"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// leafError is like the basic error string in the stdlib except the
|
||||
// message can contain redactable and non-redactable parts.
|
||||
type leafError struct {
|
||||
msg redact.RedactableString
|
||||
}
|
||||
|
||||
var _ error = (*leafError)(nil)
|
||||
var _ fmt.Formatter = (*leafError)(nil)
|
||||
var _ errbase.SafeFormatter = (*leafError)(nil)
|
||||
var _ errbase.SafeDetailer = (*leafError)(nil)
|
||||
|
||||
func (l *leafError) Error() string { return l.msg.StripMarkers() }
|
||||
func (l *leafError) Format(s fmt.State, verb rune) { errbase.FormatError(l, s, verb) }
|
||||
func (l *leafError) SafeFormatError(p errbase.Printer) (next error) {
|
||||
p.Print(l.msg)
|
||||
return nil
|
||||
}
|
||||
func (l *leafError) SafeDetails() []string {
|
||||
return []string{l.msg.Redact().StripMarkers()}
|
||||
}
|
||||
|
||||
func encodeLeaf(_ context.Context, err error) (string, []string, proto.Message) {
|
||||
l := err.(*leafError)
|
||||
return l.Error(), l.SafeDetails(), &errorspb.StringPayload{Msg: string(l.msg)}
|
||||
}
|
||||
|
||||
func decodeLeaf(_ context.Context, _ string, _ []string, payload proto.Message) error {
|
||||
m, ok := payload.(*errorspb.StringPayload)
|
||||
if !ok {
|
||||
// If this ever happens, this means some version of the library
|
||||
// (presumably future) changed the payload type, and we're
|
||||
// receiving this here. In this case, give up and let
|
||||
// DecodeError use the opaque type.
|
||||
return nil
|
||||
}
|
||||
return &leafError{msg: redact.RedactableString(m.Msg)}
|
||||
}
|
||||
|
||||
func init() {
|
||||
errbase.RegisterLeafEncoder(errbase.GetTypeKey((*leafError)(nil)), encodeLeaf)
|
||||
errbase.RegisterLeafDecoder(errbase.GetTypeKey((*leafError)(nil)), decodeLeaf)
|
||||
}
|
||||
|
||||
// withPrefix is like withMessage but the
|
||||
// message can contain redactable and non-redactable parts.
|
||||
type withPrefix struct {
|
||||
cause error
|
||||
prefix redact.RedactableString
|
||||
}
|
||||
|
||||
var _ error = (*withPrefix)(nil)
|
||||
var _ fmt.Formatter = (*withPrefix)(nil)
|
||||
var _ errbase.SafeFormatter = (*withPrefix)(nil)
|
||||
var _ errbase.SafeDetailer = (*withPrefix)(nil)
|
||||
|
||||
func (l *withPrefix) Error() string {
|
||||
if l.prefix == "" {
|
||||
return l.cause.Error()
|
||||
}
|
||||
return fmt.Sprintf("%s: %v", l.prefix.StripMarkers(), l.cause)
|
||||
}
|
||||
|
||||
func (l *withPrefix) Cause() error { return l.cause }
|
||||
func (l *withPrefix) Unwrap() error { return l.cause }
|
||||
|
||||
func (l *withPrefix) Format(s fmt.State, verb rune) { errbase.FormatError(l, s, verb) }
|
||||
func (l *withPrefix) SafeFormatError(p errbase.Printer) (next error) {
|
||||
p.Print(l.prefix)
|
||||
return l.cause
|
||||
}
|
||||
|
||||
func (l *withPrefix) SafeDetails() []string {
|
||||
return []string{l.prefix.Redact().StripMarkers()}
|
||||
}
|
||||
|
||||
func encodeWithPrefix(_ context.Context, err error) (string, []string, proto.Message) {
|
||||
l := err.(*withPrefix)
|
||||
return l.Error(), l.SafeDetails(), &errorspb.StringPayload{Msg: string(l.prefix)}
|
||||
}
|
||||
|
||||
func decodeWithPrefix(
|
||||
_ context.Context, cause error, _ string, _ []string, payload proto.Message,
|
||||
) error {
|
||||
m, ok := payload.(*errorspb.StringPayload)
|
||||
if !ok {
|
||||
// If this ever happens, this means some version of the library
|
||||
// (presumably future) changed the payload type, and we're
|
||||
// receiving this here. In this case, give up and let
|
||||
// DecodeError use the opaque type.
|
||||
return nil
|
||||
}
|
||||
return &withPrefix{cause: cause, prefix: redact.RedactableString(m.Msg)}
|
||||
}
|
||||
|
||||
func init() {
|
||||
errbase.RegisterWrapperEncoder(errbase.GetTypeKey((*withPrefix)(nil)), encodeWithPrefix)
|
||||
errbase.RegisterWrapperDecoder(errbase.GetTypeKey((*withPrefix)(nil)), decodeWithPrefix)
|
||||
}
|
||||
|
||||
// withNewMessage is like withPrefix but the message completely
|
||||
// overrides that of the underlying error.
|
||||
type withNewMessage struct {
|
||||
cause error
|
||||
message redact.RedactableString
|
||||
}
|
||||
|
||||
var _ error = (*withNewMessage)(nil)
|
||||
var _ fmt.Formatter = (*withNewMessage)(nil)
|
||||
var _ errbase.SafeFormatter = (*withNewMessage)(nil)
|
||||
var _ errbase.SafeDetailer = (*withNewMessage)(nil)
|
||||
|
||||
func (l *withNewMessage) Error() string {
|
||||
return l.message.StripMarkers()
|
||||
}
|
||||
|
||||
func (l *withNewMessage) Cause() error { return l.cause }
|
||||
func (l *withNewMessage) Unwrap() error { return l.cause }
|
||||
|
||||
func (l *withNewMessage) Format(s fmt.State, verb rune) { errbase.FormatError(l, s, verb) }
|
||||
func (l *withNewMessage) SafeFormatError(p errbase.Printer) (next error) {
|
||||
p.Print(l.message)
|
||||
return nil /* nil here overrides the cause's message */
|
||||
}
|
||||
|
||||
func (l *withNewMessage) SafeDetails() []string {
|
||||
return []string{l.message.Redact().StripMarkers()}
|
||||
}
|
||||
|
||||
func encodeWithNewMessage(_ context.Context, err error) (string, []string, proto.Message) {
|
||||
l := err.(*withNewMessage)
|
||||
return l.Error(), l.SafeDetails(), &errorspb.StringPayload{Msg: string(l.message)}
|
||||
}
|
||||
|
||||
func decodeWithNewMessage(
|
||||
_ context.Context, cause error, _ string, _ []string, payload proto.Message,
|
||||
) error {
|
||||
m, ok := payload.(*errorspb.StringPayload)
|
||||
if !ok {
|
||||
// If this ever happens, this means some version of the library
|
||||
// (presumably future) changed the payload type, and we're
|
||||
// receiving this here. In this case, give up and let
|
||||
// DecodeError use the opaque type.
|
||||
return nil
|
||||
}
|
||||
return &withNewMessage{cause: cause, message: redact.RedactableString(m.Msg)}
|
||||
}
|
||||
|
||||
func init() {
|
||||
errbase.RegisterWrapperEncoder(errbase.GetTypeKey((*withNewMessage)(nil)), encodeWithNewMessage)
|
||||
errbase.RegisterWrapperDecoder(errbase.GetTypeKey((*withNewMessage)(nil)), decodeWithNewMessage)
|
||||
}
|
||||
168
vendor/github.com/cockroachdb/errors/errutil/utilities.go
generated
vendored
Normal file
168
vendor/github.com/cockroachdb/errors/errutil/utilities.go
generated
vendored
Normal file
@@ -0,0 +1,168 @@
|
||||
// Copyright 2019 The Cockroach Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
// implied. See the License for the specific language governing
|
||||
// permissions and limitations under the License.
|
||||
|
||||
package errutil
|
||||
|
||||
import (
|
||||
"github.com/cockroachdb/errors/join"
|
||||
"github.com/cockroachdb/errors/secondary"
|
||||
"github.com/cockroachdb/errors/withstack"
|
||||
"github.com/cockroachdb/redact"
|
||||
)
|
||||
|
||||
// New creates an error with a simple error message.
|
||||
// A stack trace is retained.
|
||||
//
|
||||
// Note: the message string is assumed to not contain
|
||||
// PII and is included in Sentry reports.
|
||||
// Use errors.Newf("%s", <unsafestring>) for errors
|
||||
// strings that may contain PII information.
|
||||
//
|
||||
// Detail output:
|
||||
// - message via `Error()` and formatting using `%v`/`%s`/`%q`.
|
||||
// - everything when formatting with `%+v`.
|
||||
// - stack trace and message via `errors.GetSafeDetails()`.
|
||||
// - stack trace and message in Sentry reports.
|
||||
func New(msg string) error {
|
||||
return NewWithDepth(1, msg)
|
||||
}
|
||||
|
||||
// NewWithDepth is like New() except the depth to capture the stack
|
||||
// trace is configurable.
|
||||
// See the doc of `New()` for more details.
|
||||
func NewWithDepth(depth int, msg string) error {
|
||||
err := error(&leafError{redact.Sprint(redact.Safe(msg))})
|
||||
err = withstack.WithStackDepth(err, 1+depth)
|
||||
return err
|
||||
}
|
||||
|
||||
// Newf creates an error with a formatted error message.
|
||||
// A stack trace is retained.
|
||||
//
|
||||
// Note: the format string is assumed to not contain
|
||||
// PII and is included in Sentry reports.
|
||||
// Use errors.Newf("%s", <unsafestring>) for errors
|
||||
// strings that may contain PII information.
|
||||
//
|
||||
// See the doc of `New()` for more details.
|
||||
func Newf(format string, args ...interface{}) error {
|
||||
return NewWithDepthf(1, format, args...)
|
||||
}
|
||||
|
||||
// NewWithDepthf is like Newf() except the depth to capture the stack
|
||||
// trace is configurable.
|
||||
// See the doc of `New()` for more details.
|
||||
func NewWithDepthf(depth int, format string, args ...interface{}) error {
|
||||
// If there's the verb %w in here, shortcut to fmt.Errorf()
|
||||
// and store the safe details as extra payload. That's
|
||||
// because we don't want to re-implement the error wrapping
|
||||
// logic from 'fmt' in there.
|
||||
var err error
|
||||
var errRefs []error
|
||||
for _, a := range args {
|
||||
if e, ok := a.(error); ok {
|
||||
errRefs = append(errRefs, e)
|
||||
}
|
||||
}
|
||||
redactable, wrappedErr := redact.HelperForErrorf(format, args...)
|
||||
if wrappedErr != nil {
|
||||
err = &withNewMessage{cause: wrappedErr, message: redactable}
|
||||
} else {
|
||||
err = &leafError{redactable}
|
||||
}
|
||||
for _, e := range errRefs {
|
||||
err = secondary.WithSecondaryError(err, e)
|
||||
}
|
||||
err = withstack.WithStackDepth(err, 1+depth)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wrap wraps an error with a message prefix.
|
||||
// A stack trace is retained.
|
||||
//
|
||||
// Note: the prefix string is assumed to not contain
|
||||
// PII and is included in Sentry reports.
|
||||
// Use errors.Wrapf(err, "%s", <unsafestring>) for errors
|
||||
// strings that may contain PII information.
|
||||
//
|
||||
// Detail output:
|
||||
// - original error message + prefix via `Error()` and formatting using `%v`/`%s`/`%q`.
|
||||
// - everything when formatting with `%+v`.
|
||||
// - stack trace and message via `errors.GetSafeDetails()`.
|
||||
// - stack trace and message in Sentry reports.
|
||||
func Wrap(err error, msg string) error {
|
||||
return WrapWithDepth(1, err, msg)
|
||||
}
|
||||
|
||||
// WrapWithDepth is like Wrap except the depth to capture the stack
|
||||
// trace is configurable.
|
||||
// The the doc of `Wrap()` for more details.
|
||||
func WrapWithDepth(depth int, err error, msg string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if msg != "" {
|
||||
err = WithMessage(err, msg)
|
||||
}
|
||||
err = withstack.WithStackDepth(err, depth+1)
|
||||
return err
|
||||
}
|
||||
|
||||
// Wrapf wraps an error with a formatted message prefix. A stack
|
||||
// trace is also retained. If the format is empty, no prefix is added,
|
||||
// but the extra arguments are still processed for reportable strings.
|
||||
//
|
||||
// Note: the format string is assumed to not contain
|
||||
// PII and is included in Sentry reports.
|
||||
// Use errors.Wrapf(err, "%s", <unsafestring>) for errors
|
||||
// strings that may contain PII information.
|
||||
//
|
||||
// Detail output:
|
||||
// - original error message + prefix via `Error()` and formatting using `%v`/`%s`/`%q`.
|
||||
// - everything when formatting with `%+v`.
|
||||
// - stack trace, format, and redacted details via `errors.GetSafeDetails()`.
|
||||
// - stack trace, format, and redacted details in Sentry reports.
|
||||
func Wrapf(err error, format string, args ...interface{}) error {
|
||||
return WrapWithDepthf(1, err, format, args...)
|
||||
}
|
||||
|
||||
// WrapWithDepthf is like Wrapf except the depth to capture the stack
|
||||
// trace is configurable.
|
||||
// The the doc of `Wrapf()` for more details.
|
||||
func WrapWithDepthf(depth int, err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
var errRefs []error
|
||||
for _, a := range args {
|
||||
if e, ok := a.(error); ok {
|
||||
errRefs = append(errRefs, e)
|
||||
}
|
||||
}
|
||||
if format != "" || len(args) > 0 {
|
||||
err = WithMessagef(err, format, args...)
|
||||
}
|
||||
for _, e := range errRefs {
|
||||
err = secondary.WithSecondaryError(err, e)
|
||||
}
|
||||
err = withstack.WithStackDepth(err, depth+1)
|
||||
return err
|
||||
}
|
||||
|
||||
// JoinWithDepth constructs a Join error with the provided list of
|
||||
// errors as arguments, and wraps it in a `WithStackDepth` to capture a
|
||||
// stacktrace alongside.
|
||||
func JoinWithDepth(depth int, errs ...error) error {
|
||||
return withstack.WithStackDepth(join.Join(errs...), depth+1)
|
||||
}
|
||||
Reference in New Issue
Block a user