Initial commit
This commit is contained in:
124
vendor/github.com/cockroachdb/errors/barriers/barriers.go
generated
vendored
Normal file
124
vendor/github.com/cockroachdb/errors/barriers/barriers.go
generated
vendored
Normal file
@@ -0,0 +1,124 @@
|
||||
// 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 barriers
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/cockroachdb/errors/errbase"
|
||||
"github.com/gogo/protobuf/proto"
|
||||
)
|
||||
|
||||
// Handled swallows the provided error and hides it from the
|
||||
// Cause()/Unwrap() interface, and thus the Is() facility that
|
||||
// identifies causes. However, it retains it for the purpose of
|
||||
// printing the error out (e.g. for troubleshooting). The error
|
||||
// message is preserved in full.
|
||||
//
|
||||
// Detail is shown:
|
||||
// - via `errors.GetSafeDetails()`, shows details from hidden error.
|
||||
// - when formatting with `%+v`.
|
||||
// - in Sentry reports.
|
||||
func Handled(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return HandledWithMessage(err, err.Error())
|
||||
}
|
||||
|
||||
// HandledWithMessage is like Handled except the message is overridden.
|
||||
// This can be used e.g. to hide message details or to prevent
|
||||
// downstream code to make assertions on the message's contents.
|
||||
func HandledWithMessage(err error, msg string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &barrierError{maskedErr: err, msg: msg}
|
||||
}
|
||||
|
||||
// HandledWithMessagef is like HandledWithMessagef except the message
|
||||
// is formatted.
|
||||
func HandledWithMessagef(err error, format string, args ...interface{}) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return &barrierError{maskedErr: err, msg: fmt.Sprintf(format, args...)}
|
||||
}
|
||||
|
||||
// barrierError is a leaf error type. It encapsulates a chain of
|
||||
// original causes, but these causes are hidden so that they inhibit
|
||||
// matching via Is() and the Cause()/Unwrap() recursions.
|
||||
type barrierError struct {
|
||||
// Message for the barrier itself.
|
||||
// In the common case, the message from the masked error
|
||||
// is used as-is (see Handled() above) however it is
|
||||
// useful to cache it here since the masked error may
|
||||
// have a long chain of wrappers and its Error() call
|
||||
// may be expensive.
|
||||
msg string
|
||||
// Masked error chain.
|
||||
maskedErr error
|
||||
}
|
||||
|
||||
var _ error = (*barrierError)(nil)
|
||||
var _ errbase.SafeDetailer = (*barrierError)(nil)
|
||||
var _ errbase.SafeFormatter = (*barrierError)(nil)
|
||||
var _ fmt.Formatter = (*barrierError)(nil)
|
||||
|
||||
// barrierError is an error.
|
||||
func (e *barrierError) Error() string { return e.msg }
|
||||
|
||||
// SafeDetails reports the PII-free details from the masked error.
|
||||
func (e *barrierError) SafeDetails() []string {
|
||||
var details []string
|
||||
for err := e.maskedErr; err != nil; err = errbase.UnwrapOnce(err) {
|
||||
sd := errbase.GetSafeDetails(err)
|
||||
details = sd.Fill(details)
|
||||
}
|
||||
return details
|
||||
}
|
||||
|
||||
// Printing a barrier reveals the details.
|
||||
func (e *barrierError) Format(s fmt.State, verb rune) { errbase.FormatError(e, s, verb) }
|
||||
|
||||
func (e *barrierError) SafeFormatError(p errbase.Printer) (next error) {
|
||||
p.Print(e.msg)
|
||||
if p.Detail() {
|
||||
p.Printf("-- cause hidden behind barrier\n%+v", e.maskedErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A barrier error is encoded exactly.
|
||||
func encodeBarrier(
|
||||
ctx context.Context, err error,
|
||||
) (msg string, details []string, payload proto.Message) {
|
||||
e := err.(*barrierError)
|
||||
enc := errbase.EncodeError(ctx, e.maskedErr)
|
||||
return e.msg, e.SafeDetails(), &enc
|
||||
}
|
||||
|
||||
// A barrier error is decoded exactly.
|
||||
func decodeBarrier(ctx context.Context, msg string, _ []string, payload proto.Message) error {
|
||||
enc := payload.(*errbase.EncodedError)
|
||||
return &barrierError{msg: msg, maskedErr: errbase.DecodeError(ctx, *enc)}
|
||||
}
|
||||
|
||||
func init() {
|
||||
tn := errbase.GetTypeKey((*barrierError)(nil))
|
||||
errbase.RegisterLeafDecoder(tn, decodeBarrier)
|
||||
errbase.RegisterLeafEncoder(tn, encodeBarrier)
|
||||
}
|
||||
Reference in New Issue
Block a user