rebase: vendor files required for kmip

Signed-off-by: Rakshith R <rar@redhat.com>
This commit is contained in:
Rakshith R
2022-08-16 15:18:06 +05:30
committed by mergify[bot]
parent 0c33a33d5c
commit e72ed593be
186 changed files with 39195 additions and 203 deletions

50
vendor/github.com/ansel1/merry/.gitignore generated vendored Normal file
View File

@ -0,0 +1,50 @@
# Created by .ignore support plugin (hsz.mobi)
### JetBrains template
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion
*.iml
## Directory-based project format:
.idea/
# if you remove the above rule, at least ignore the following:
# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml
# Gradle:
# .idea/gradle.xml
# .idea/libraries
# Mongo Explorer plugin:
# .idea/mongoSettings.xml
## File-based project format:
*.ipr
*.iws
## Plugin-specific files:
# IntelliJ
/out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
vendor/

21
vendor/github.com/ansel1/merry/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Russ Egan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

44
vendor/github.com/ansel1/merry/Makefile generated vendored Normal file
View File

@ -0,0 +1,44 @@
# Expands to list this project's go packages, excluding the vendor folder
SHELL = bash
all: fmt build test lint v2
v2:
$(MAKE) -C v2
build:
go build
lint:
golint -set_exit_status
clean:
rm -rf build
fmt:
go fmt ./...
test:
go test ./...
testall:
go test -count 1 ./...
coverage:
@if [ ! -d build ]; then mkdir build; fi
# runs go test and generate coverage report
go test -covermode=count -coverprofile=build/coverage.out ./...
go tool cover -html=build/coverage.out -o build/coverage.html
bench:
go test -bench ./...
### TOOLS
tools:
go get -u golang.org/x/tools/cmd/cover
go get -u golang.org/x/lint/golint
.PHONY: all build lint clean fmt test coverage tools v2

255
vendor/github.com/ansel1/merry/README.md generated vendored Normal file
View File

@ -0,0 +1,255 @@
merry [![Build](https://github.com/ansel1/merry/workflows/Build/badge.svg)](https://github.com/ansel1/merry/actions?query=branch%3Amaster+workflow%3ABuild+) [![GoDoc](https://godoc.org/github.com/ansel1/merry?status.png)](https://godoc.org/github.com/ansel1/merry) [![Go Report Card](https://goreportcard.com/badge/github.com/ansel1/merry)](https://goreportcard.com/report/github.com/ansel1/merry)
=====
Add context to errors, including automatic stack capture, cause chains, HTTP status code, user
messages, and arbitrary values.
The package is largely based on http://github.com/go-errors/errors, with additional
inspiration from https://github.com/go-errgo/errgo and https://github.com/amattn/deeperror.
V2
--
[github.com/ansel1/merry/v2](https://github.com/ansel1/merry/tree/master/v2) now replaces v1. v1 will continue to be supported. v1 has been re-implemented
in terms of v2, and the two packages can be used together and interchangeably.
There are some small enhancements and changes to v1 with the introduction of v2:
- err.Error() now *always* just prints out the basic error message. It no longer prints out details,
user message, or cause. VerboseDefault() and SetVerboseDefault() no longer have any effect. To
print more detailed error information, you must use fmt:
// print err message and cause chain
fmt.Printf("%v", err) // %s works too
// print details, same as Details(err)
fmt.Printf("%v+", err)
- MaxStackDepth is no longer supported. Setting it has no effect. It has been replaced with
GetMaxStackDepth() and SetMaxStackDepth(), which delegate to corresponding v2 functions.
- New, Errorf, Wrap, and WrapSkipping now accept v2.Wrapper arguments, allowing a mixture of
v1's fluent API style and v2's option-func API style.
- Compatibility with other error wrapping libraries is improved. All functions which extract
a value from an error will now search the entire chain of errors, even if errors created by
other libraries are inserted in the middle of the chain, so long as those errors implement
Unwrap().
Installation
------------
go get github.com/ansel1/merry
Features
--------
Merry errors work a lot like google's golang.org/x/net/context package.
Merry errors wrap normal errors with a context of key/value pairs.
Like contexts, merry errors are immutable: adding a key/value to an error
always creates a new error which wraps the original.
`merry` comes with built-in support for adding information to errors:
* stacktraces
* overriding the error message
* HTTP status codes
* End user error messages
You can also add your own additional information.
The stack capturing feature can be turned off for better performance, though it's pretty fast. Benchmarks
on an 2017 MacBook Pro, with go 1.10:
BenchmarkNew_withStackCapture-8 2000000 749 ns/op
BenchmarkNew_withoutStackCapture-8 20000000 64.1 ns/op
Details
-------
* Support for go 2's errors.Is and errors.As functions
* New errors have a stacktrace captured where they are created
* Add a stacktrace to existing errors (captured where they are wrapped)
```go
err := lib.Read()
return merry.Wrap(err) // no-op if err is already merry
```
* Add a stacktrace to a sentinel error
```go
var ParseError = merry.New("parse error")
func Parse() error {
// ...
return ParseError.Here() // captures a stacktrace here
}
```
* The golang idiom for testing errors against sentinel values or type checking them
doesn't work with merry errors, since they are wrapped. Use Is() for sentinel value
checks, or the new go 2 errors.As() function for testing error types.
```go
err := Parse()
// sentinel value check
if merry.Is(err, ParseError) {
// ...
}
// type check
if serr, ok := merry.Unwrap(err).(*SyntaxError); ok {
// ...
}
// these only work in go1.13
// sentinel value check
if errors.Is(err, ParseError) {}
// type check
var serr *SyntaxError
if errors.As(err, &serr) {}
```
* Add to the message on an error.
```go
err := merry.Prepend(ParseError, "reading config").Append("bad input")
fmt.Println(err.Error()) // reading config: parse error: bad input
```
* Hierarchies of errors
```go
var ParseError = merry.New("Parse error")
var InvalidCharSet = merry.WithMessage(ParseError, "Invalid char set")
var InvalidSyntax = merry.WithMessage(ParseError, "Invalid syntax")
func Parse(s string) error {
// use chainable methods to add context
return InvalidCharSet.Here().WithMessagef("Invalid char set: %s", "UTF-8")
// or functions
// return merry.WithMessagef(merry.Here(InvalidCharSet), "Invalid char set: %s", "UTF-8")
}
func Check() {
err := Parse("fields")
merry.Is(err, ParseError) // yup
merry.Is(err, InvalidCharSet) // yup
merry.Is(err, InvalidSyntax) // nope
}
```
* Add an HTTP status code
```go
merry.HTTPCode(errors.New("regular error")) // 500
merry.HTTPCode(merry.New("merry error").WithHTTPCode(404)) // 404
```
* Set an alternate error message for end users
```go
e := merry.New("crash").WithUserMessage("nothing to see here")
merry.UserMessage(e) // returns "nothing to see here"
```
* Functions for printing error details
```go
err := merry.New("boom")
m := merry.Stacktrace(err) // just the stacktrace
m = merry.Details(err) // error message and stacktrace
fmt.Sprintf("%+v", err) == merry.Details(err) // errors implement fmt.Formatter
```
* Add your own context info
```go
err := merry.New("boom").WithValue("explosive", "black powder")
```
Basic Usage
-----------
The package contains functions for creating new errors with stacks, or adding a stack to `error`
instances. Functions with add context (e.g. `WithValue()`) work on any `error`, and will
automatically convert them to merry errors (with a stack) if necessary.
Capturing the stack can be globally disabled with `SetStackCaptureEnabled(false)`
Functions which get context values from errors also accept `error`, and will return default
values if the error is not merry, or doesn't have that key attached.
All the functions which create or attach context return concrete instances of `*Error`. `*Error`
implements methods to add context to the error (they mirror the functions and do
the same thing). They allow for a chainable syntax for adding context.
Example:
```go
package main
import (
"github.com/ansel1/merry"
"errors"
)
var InvalidInputs = errors.New("Input is invalid")
func main() {
// create a new error, with a stacktrace attached
err := merry.New("bad stuff happened")
// create a new error with format string, like fmt.Errorf
err = merry.Errorf("bad input: %v", os.Args)
// capture a fresh stacktrace from this callsite
err = merry.Here(InvalidInputs)
// Make err merry if it wasn't already. The stacktrace will be captured here if the
// error didn't already have one. Also useful to cast to *Error
err = merry.Wrap(err, 0)
// override the original error's message
err.WithMessagef("Input is invalid: %v", os.Args)
// Use Is to compare errors against values, which is a common golang idiom
merry.Is(err, InvalidInputs) // will be true
// associated an http code
err.WithHTTPCode(400)
perr := parser.Parse("blah")
err = Wrap(perr, 0)
// Get the original error back
merry.Unwrap(err) == perr // will be true
// Print the error to a string, with the stacktrace, if it has one
s := merry.Details(err)
// Just print the stacktrace (empty string if err is not a RichError)
s := merry.Stacktrace(err)
// Get the location of the error (the first line in the stacktrace)
file, line := merry.Location(err)
// Get an HTTP status code for an error. Defaults to 500 for non-nil errors, and 200 if err is nil.
code := merry.HTTPCode(err)
}
```
See inline docs for more details.
Plugs
-----
- Check out my HTTP client library: [github.com/gemalto/requester](https://github.com/gemalto/requester)
- Check out my log library: [github.com/gemalto/flume](https://github.com/gemalto/flume)
License
-------
This package is licensed under the MIT license, see LICENSE.MIT for details.

152
vendor/github.com/ansel1/merry/chainable_api.go generated vendored Normal file
View File

@ -0,0 +1,152 @@
package merry
import (
"fmt"
v2 "github.com/ansel1/merry/v2"
"io"
)
// Error extends the standard golang `error` interface with functions
// for attachment additional data to the error
type Error interface {
error
Appendf(format string, args ...interface{}) Error
Append(msg string) Error
Prepend(msg string) Error
Prependf(format string, args ...interface{}) Error
WithMessage(msg string) Error
WithMessagef(format string, args ...interface{}) Error
WithUserMessage(msg string) Error
WithUserMessagef(format string, args ...interface{}) Error
WithValue(key, value interface{}) Error
Here() Error
WithStackSkipping(skip int) Error
WithHTTPCode(code int) Error
WithCause(err error) Error
Cause() error
fmt.Formatter
}
// make sure errImpl implements Error
var _ Error = (*errImpl)(nil)
// WithValue is equivalent to WithValue(e, key, value).
func (e *errImpl) WithValue(key, value interface{}) Error {
return WrapSkipping(e, 1, v2.WithValue(key, value))
}
// Here is equivalent to Here(e).
func (e *errImpl) Here() Error {
return HereSkipping(e, 1)
}
// WithStackSkipping is equivalent to HereSkipping(e, i).
func (e *errImpl) WithStackSkipping(skip int) Error {
return HereSkipping(e, skip+1)
}
// WithHTTPCode is equivalent to WithHTTPCode(e, code).
func (e *errImpl) WithHTTPCode(code int) Error {
return WrapSkipping(e, 1, v2.WithHTTPCode(code))
}
// WithMessage is equivalent to WithMessage(e, msg).
func (e *errImpl) WithMessage(msg string) Error {
return WrapSkipping(e, 1, v2.WithMessage(msg))
}
// WithMessagef is equivalent to WithMessagef(e, format, args...).
func (e *errImpl) WithMessagef(format string, args ...interface{}) Error {
return WrapSkipping(e, 1, v2.WithMessagef(format, args...))
}
// WithUserMessage is equivalent to WithUserMessage(e, msg).
func (e *errImpl) WithUserMessage(msg string) Error {
return WrapSkipping(e, 1, v2.WithUserMessage(msg))
}
// WithUserMessagef is equivalent to WithUserMessagef(e, format, args...).
func (e *errImpl) WithUserMessagef(format string, args ...interface{}) Error {
return WrapSkipping(e, 1, v2.WithUserMessagef(format, args...))
}
// Append is equivalent to Append(err, msg).
func (e *errImpl) Append(msg string) Error {
return WrapSkipping(e, 1, v2.AppendMessage(msg))
}
// Appendf is equivalent to Appendf(err, format, msg).
func (e *errImpl) Appendf(format string, args ...interface{}) Error {
return WrapSkipping(e, 1, v2.AppendMessagef(format, args...))
}
// Prepend is equivalent to Prepend(err, msg).
func (e *errImpl) Prepend(msg string) Error {
return WrapSkipping(e, 1, v2.PrependMessage(msg))
}
// Prependf is equivalent to Prependf(err, format, args...).
func (e *errImpl) Prependf(format string, args ...interface{}) Error {
return WrapSkipping(e, 1, v2.PrependMessagef(format, args...))
}
// WithCause is equivalent to WithCause(e, err).
func (e *errImpl) WithCause(err error) Error {
return WrapSkipping(e, 1, v2.WithCause(err))
}
// errImpl coerces an error to an Error
type errImpl struct {
err error
}
func coerce(err error) Error {
if err == nil {
return nil
}
if e, ok := err.(Error); ok {
return e
}
return &errImpl{err}
}
// Format implements fmt.Formatter.
func (e *errImpl) Format(s fmt.State, verb rune) {
// the inner err should always be an err produced
// by v2
if f, ok := e.err.(fmt.Formatter); ok {
f.Format(s, verb)
return
}
// should never happen, but fall back on something
switch verb {
case 'v':
if s.Flag('+') {
_, _ = io.WriteString(s, Details(e))
return
}
fallthrough
case 's':
_, _ = io.WriteString(s, e.Error())
case 'q':
_, _ = fmt.Fprintf(s, "%q", e.Error())
}
}
// Error implements the error interface.
func (e *errImpl) Error() string {
return e.err.Error()
}
// Unwrap returns the next wrapped error.
func (e *errImpl) Unwrap() error {
return e.err
}
// Cause implements Error.
func (e *errImpl) Cause() error {
return Cause(e.err)
}

90
vendor/github.com/ansel1/merry/doc.go generated vendored Normal file
View File

@ -0,0 +1,90 @@
// Package merry provides enriched golang errors, with stacktraces
//
// merry creates errors with stacktraces, and can augment those errors with additional
// information.
//
// When you create a new merry error, or wrap an existing error in a merry error, merry attaches
// a stacktrace to the error:
//
// err := merry.New("an error occurred")
//
// err has a stacktrace attached. Alternately, you can wrap existing errors. merry will
// attach a stacktrace at the point of wrapping:
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return merry.Wrap(err)
// }
//
// Capturing the stack can be globally disabled with `SetStackCaptureEnabled(false)`. Wrapping
// is idempotent: Wrap will only attach a stacktrace if the error doesn't already have one.
//
// Wrap() is the simplest way to attach a stacktrace to an error, but other functions can be
// used instead, with both add a stacktrace, and augment or modify the error. For example,
// Prepend() modifies the error's message (and also attaches a stacktrace):
//
// _, err := ioutil.ReadAll(r)
// if err != nil {
// return merry.Prepend(err, "reading from conn failed")
// // err.Error() would read something like "reading from conn failed: timeout"
// }
//
// See the other package functions for other ways to augment or modify errors, such as Append,
// WithUserMessage, WithHTTPCode, WithValue, etc. These functions all return a merry.Error interface, which
// has methods which mirror the package level functions, to allow simple chaining:
//
// return merry.New("object not found").WithHTTPCode(404)
//
// Here
//
// Wrap will not take a new stacktrace if an error already has one attached. Here will create
// a new error which replaces the stacktrace with a new one:
//
// var ErrOverflow = merry.New("overflowed")
//
// func Read() error {
// // ...
// return merry.Here(ErrOverflow)
// }
//
// Is
//
// The go idiom of exporting package-level error variables for comparison to errors returned
// by the package is broken by merry. For example:
//
// _, err := io.ReadAll(r)
// if err == io.EOF {
// // ...
// }
//
// If the error returned was a merry error, the equality comparison would always fail, because merry
// augments errors by wrapping them in layers. To compensate for this, merry has the Is() function.
//
// if merry.Is(err, io.EOF) {
//
// Is() will unwrap the err and compare each layer to the second argument.
//
// Cause
//
// You can add a cause to an error:
//
// if err == io.EOF {
// err = merry.New("reading failed"), err)
// fmt.Println(err.Error()) // reading failed: EOF
// }
//
// Cause(error) will return the cause of the argument. RootCause(error) returns the innermost cause.
// Is(err1, err2) is cause aware, and will return true if err2 is a cause (anywhere in the causal change)
// of err1.
//
// Formatting and printing
//
// To obtain an error's stacktrace, call Stack(). To get other information about the site
// of the error, or print the error's stacktrace, see Location(), SourceLine(), Stacktrace(), and Details().
//
// merry errors also implement the fmt.Formatter interface. errors support the following fmt flags:
//
// %+v print the equivalent of Details(err), which includes the user message, full stacktrace,
// and recursively prints the details of the cause chain.
//
package merry

304
vendor/github.com/ansel1/merry/errors.go generated vendored Normal file
View File

@ -0,0 +1,304 @@
package merry
// The merry package augments standard golang errors with stacktraces
// and other context information.
//
// You can add any context information to an error with `e = merry.WithValue(e, "code", 12345)`
// You can retrieve that value with `v, _ := merry.Value(e, "code").(int)`
//
// Any error augmented like this will automatically get a stacktrace attached, if it doesn't have one
// already. If you just want to add the stacktrace, use `Wrap(e)`
//
// It also providers a way to override an error's message:
//
// var InvalidInputs = errors.New("Bad inputs")
//
// `Here()` captures a new stacktrace, and WithMessagef() sets a new error message:
//
// return merry.Here(InvalidInputs).WithMessagef("Bad inputs: %v", inputs)
//
// Errors are immutable. All functions and methods which add context return new errors.
// But errors can still be compared to the originals with `Is()`
//
// if merry.Is(err, InvalidInputs) {
//
// Functions which add context to errors have equivalent methods on *Error, to allow
// convenient chaining:
//
// return merry.New("Invalid body").WithHTTPCode(400)
//
// merry.Errors also implement fmt.Formatter, similar to github.com/pkg/errors.
//
// fmt.Sprintf("%+v", e) == merry.Details(e)
//
// pkg/errors Cause() interface is not implemented (yet).
import (
"errors"
"fmt"
v2 "github.com/ansel1/merry/v2"
)
// MaxStackDepth is no longer used. It remains here for backward compatibility.
// deprecated: See Set/GetMaxStackDepth.
var MaxStackDepth = 50
// StackCaptureEnabled returns whether stack capturing is enabled
func StackCaptureEnabled() bool {
return v2.StackCaptureEnabled()
}
// SetStackCaptureEnabled sets stack capturing globally. Disabling stack capture can increase performance
func SetStackCaptureEnabled(enabled bool) {
v2.SetStackCaptureEnabled(enabled)
}
// VerboseDefault no longer has any effect.
// deprecated: see SetVerboseDefault
func VerboseDefault() bool {
return false
}
// SetVerboseDefault used to control the behavior of the Error() function on errors
// processed by this package. Error() now always just returns the error's message.
// This setting no longer has any effect.
// deprecated: To print the details of an error, use Details(err), or format the
// error with the verbose flag: fmt.Sprintf("%+v", err)
func SetVerboseDefault(bool) {
}
// GetMaxStackDepth returns the number of frames captured in stacks.
func GetMaxStackDepth() int {
return v2.MaxStackDepth()
}
// SetMaxStackDepth sets the MaxStackDepth.
func SetMaxStackDepth(depth int) {
v2.SetMaxStackDepth(depth)
}
// New creates a new error, with a stack attached. The equivalent of golang's errors.New().
// Accepts v2 wrappers to apply to the error.
func New(msg string, wrappers ...v2.Wrapper) Error {
return WrapSkipping(errors.New(msg), 1, wrappers...)
}
// Errorf creates a new error with a formatted message and a stack. The equivalent of golang's fmt.Errorf().
// args can be format args, or v2 wrappers which will be applied to the error.
func Errorf(format string, args ...interface{}) Error {
var wrappers []v2.Wrapper
// pull out the args which are wrappers
n := 0
for _, arg := range args {
if w, ok := arg.(v2.Wrapper); ok {
wrappers = append(wrappers, w)
} else {
args[n] = arg
n++
}
}
args = args[:n]
return WrapSkipping(fmt.Errorf(format, args...), 1, wrappers...)
}
// UserError creates a new error with a message intended for display to an
// end user.
func UserError(msg string) Error {
return WrapSkipping(errors.New(msg), 1, v2.WithUserMessage(msg))
}
// UserErrorf is like UserError, but uses fmt.Sprintf()
func UserErrorf(format string, args ...interface{}) Error {
msg := fmt.Sprintf(format, args...)
return WrapSkipping(errors.New(msg), 1, v2.WithUserMessagef(msg))
}
// Wrap turns the argument into a merry.Error. If the argument already is a
// merry.Error, this is a no-op.
// If e == nil, return nil
func Wrap(err error, wrappers ...v2.Wrapper) Error {
return coerce(v2.WrapSkipping(err, 1, wrappers...))
}
// WrapSkipping turns the error arg into a merry.Error if the arg is not
// already a merry.Error.
// If e is nil, return nil.
// If a merry.Error is created by this call, the stack captured will skip
// `skip` frames (0 is the call site of `WrapSkipping()`)
func WrapSkipping(err error, skip int, wrappers ...v2.Wrapper) Error {
return coerce(v2.WrapSkipping(err, skip+1, wrappers...))
}
// WithValue adds a context an error. If the key was already set on e,
// the new value will take precedence.
// If e is nil, returns nil.
func WithValue(err error, key, value interface{}) Error {
return WrapSkipping(err, 1, v2.WithValue(key, value))
}
// Value returns the value for key, or nil if not set.
// If e is nil, returns nil.
func Value(err error, key interface{}) interface{} {
return v2.Value(err, key)
}
// Values returns a map of all values attached to the error
// If a key has been attached multiple times, the map will
// contain the last value mapped
// If e is nil, returns nil.
func Values(err error) map[interface{}]interface{} {
return v2.Values(err)
}
// RegisteredDetails extracts details registered with RegisterDetailFunc from an error, and
// returns them as a map. Values may be nil.
//
// If err is nil or there are no registered details, nil is returned.
func RegisteredDetails(err error) map[string]interface{} {
return v2.RegisteredDetails(err)
}
// Here returns an error with a new stacktrace, at the call site of Here().
// Useful when returning copies of exported package errors.
// If e is nil, returns nil.
func Here(err error) Error {
return WrapSkipping(err, 1, v2.CaptureStack(false))
}
// HereSkipping returns an error with a new stacktrace, at the call site
// of HereSkipping() - skip frames.
func HereSkipping(err error, skip int) Error {
return WrapSkipping(err, skip+1, v2.CaptureStack(false))
}
// Message returns just returns err.Error(). It is here for
// historical reasons.
func Message(err error) string {
if err == nil {
return ""
}
return err.Error()
}
// Stack returns the stack attached to an error, or nil if one is not attached
// If e is nil, returns nil.
func Stack(err error) []uintptr {
return v2.Stack(err)
}
// WithHTTPCode returns an error with an http code attached.
// If e is nil, returns nil.
func WithHTTPCode(e error, code int) Error {
return WrapSkipping(e, 1, v2.WithHTTPCode(code))
}
// HTTPCode converts an error to an http status code. All errors
// map to 500, unless the error has an http code attached.
// If e is nil, returns 200.
func HTTPCode(err error) int {
return v2.HTTPCode(err)
}
// UserMessage returns the end-user safe message. Returns empty if not set.
// If e is nil, returns "".
func UserMessage(err error) string {
return v2.UserMessage(err)
}
// Cause returns the cause of the argument. If e is nil, or has no cause,
// nil is returned.
func Cause(err error) error {
return v2.Cause(err)
}
// RootCause returns the innermost cause of the argument (i.e. the last
// error in the cause chain)
func RootCause(err error) error {
for {
cause := Cause(err)
if cause == nil {
return err
}
err = cause
}
}
// WithCause returns an error based on the first argument, with the cause
// set to the second argument. If e is nil, returns nil.
func WithCause(err error, cause error) Error {
return WrapSkipping(err, 1, v2.WithCause(cause))
}
// WithMessage returns an error with a new message.
// The resulting error's Error() method will return
// the new message.
// If e is nil, returns nil.
func WithMessage(err error, msg string) Error {
return WrapSkipping(err, 1, v2.WithMessage(msg))
}
// WithMessagef is the same as WithMessage(), using fmt.Sprintf().
func WithMessagef(err error, format string, args ...interface{}) Error {
return WrapSkipping(err, 1, v2.WithMessagef(format, args...))
}
// WithUserMessage adds a message which is suitable for end users to see.
// If e is nil, returns nil.
func WithUserMessage(err error, msg string) Error {
return WrapSkipping(err, 1, v2.WithUserMessage(msg))
}
// WithUserMessagef is the same as WithMessage(), using fmt.Sprintf()
func WithUserMessagef(err error, format string, args ...interface{}) Error {
return WrapSkipping(err, 1, v2.WithUserMessagef(format, args...))
}
// Append a message after the current error message, in the format "original: new".
// If e == nil, return nil.
func Append(err error, msg string) Error {
return WrapSkipping(err, 1, v2.AppendMessage(msg))
}
// Appendf is the same as Append, but uses fmt.Sprintf().
func Appendf(err error, format string, args ...interface{}) Error {
return WrapSkipping(err, 1, v2.AppendMessagef(format, args...))
}
// Prepend a message before the current error message, in the format "new: original".
// If e == nil, return nil.
func Prepend(err error, msg string) Error {
return WrapSkipping(err, 1, v2.PrependMessage(msg))
}
// Prependf is the same as Prepend, but uses fmt.Sprintf()
func Prependf(err error, format string, args ...interface{}) Error {
return WrapSkipping(err, 1, v2.PrependMessagef(format, args...))
}
// Is is equivalent to errors.Is, but tests against multiple targets.
//
// merry.Is(err1, err2, err3) == errors.Is(err1, err2) || errors.Is(err1, err3)
func Is(e error, originals ...error) bool {
for _, o := range originals {
if errors.Is(e, o) {
return true
}
}
return false
}
// Unwrap returns the innermost underlying error.
// This just calls errors.Unwrap() until if finds the deepest error.
// It isn't very useful, and only remains for historical purposes
//
// deprecated: use errors.Is() or errors.As() instead.
func Unwrap(e error) error {
for {
next := errors.Unwrap(e)
if next == nil {
return e
}
e = next
}
}

65
vendor/github.com/ansel1/merry/print.go generated vendored Normal file
View File

@ -0,0 +1,65 @@
package merry
import (
v2 "github.com/ansel1/merry/v2"
)
// RegisterDetail registers an error property key in a global registry, with a label.
// The registry is used by the Details() function. Registered error properties will
// be included in Details() output, if the value of that error property is not nil.
// For example:
//
// err := New("boom")
// err = err.WithValue(colorKey, "red")
// fmt.Println(Details(err))
//
// // Output:
// // boom
// //
// // <stacktrace>
//
// RegisterDetail("Color", colorKey)
// fmt.Println(Details(err))
//
// // Output:
// // boom
// // Color: red
// //
// // <stacktrace>
//
// Error property keys are typically not exported by the packages which define them.
// Packages instead export functions which let callers access that property.
// It's therefore up to the package
// to register those properties which would make sense to include in the Details() output.
// In other words, it's up to the author of the package which generates the errors
// to publish printable error details, not the callers of the package.
func RegisterDetail(label string, key interface{}) {
v2.RegisterDetail(label, key)
}
// Location returns zero values if e has no stacktrace
func Location(err error) (file string, line int) {
return v2.Location(err)
}
// SourceLine returns the string representation of
// Location's result or an empty string if there's
// no stracktrace.
func SourceLine(err error) string {
return v2.SourceLine(err)
}
// Stacktrace returns the error's stacktrace as a string formatted
// the same way as golangs runtime package.
// If e has no stacktrace, returns an empty string.
func Stacktrace(err error) string {
return v2.Stacktrace(err)
}
// Details returns e.Error(), e's stacktrace, and any additional details which have
// be registered with RegisterDetail. User message and HTTP code are already registered.
//
// The details of each error in e's cause chain will also be printed.
func Details(err error) string {
return v2.Details(err)
}

21
vendor/github.com/ansel1/merry/v2/LICENSE generated vendored Normal file
View File

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Russ Egan
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

41
vendor/github.com/ansel1/merry/v2/Makefile generated vendored Normal file
View File

@ -0,0 +1,41 @@
# Expands to list this project's go packages, excluding the vendor folder
SHELL = bash
all: fmt build test lint
build:
go build
lint:
golint -set_exit_status ./...
clean:
rm -rf build
fmt:
go fmt ./...
test:
go test ./...
testall:
go test -count 1 ./...
coverage:
@if [ ! -d build ]; then mkdir build; fi
# runs go test and generate coverage report
go test -covermode=count -coverprofile=build/coverage.out ./...
go tool cover -html=build/coverage.out -o build/coverage.html
bench:
go test -bench ./...
### TOOLS
tools:
go get -u golang.org/x/tools/cmd/cover
go get -u golang.org/x/lint/golint
.PHONY: all build lint clean fmt test coverage tools

88
vendor/github.com/ansel1/merry/v2/README.md generated vendored Normal file
View File

@ -0,0 +1,88 @@
merry [![Build](https://github.com/ansel1/merry/workflows/Build/badge.svg)](https://github.com/ansel1/merry/actions?query=branch%3Amaster+workflow%3ABuild+) [![GoDoc](https://godoc.org/github.com/ansel1/merry/v2?status.png)](https://godoc.org/github.com/ansel1/merry/v2) [![Go Report Card](https://goreportcard.com/badge/github.com/ansel1/merry/v2)](https://goreportcard.com/report/github.com/ansel1/merry/v2)
=====
Add context to errors, including automatic stack capture, cause chains, HTTP status code, user
messages, and arbitrary values.
The package is largely based on http://github.com/go-errors/errors, with additional
inspiration from https://github.com/go-errgo/errgo and https://github.com/amattn/deeperror.
Installation
------------
go get github.com/ansel1/merry/v2
Features
--------
Wrapped errors work a lot like google's golang.org/x/net/context package:
each wrapper error contains the inner error, a key, and a value.
Like contexts, errors are immutable: adding a key/value to an error
always creates a new error which wraps the original.
This package comes with built-in support for adding information to errors:
* stacktraces
* changing the error message
* HTTP status codes
* End user error messages
* causes
You can also add your own additional information.
The stack capturing feature can be turned off for better performance, though it's pretty fast. Benchmarks
on an 2017 MacBook Pro, with go 1.10:
BenchmarkNew_withStackCapture-8 2000000 749 ns/op
BenchmarkNew_withoutStackCapture-8 20000000 64.1 ns/op
Merry errors are fully compatible with errors.Is, As, and Unwrap.
Example
-------
To add a stacktrace, a user message, and an HTTP code to an error:
err = merry.Wrap(err, WithUserMessagef("Username %s not found.", username), WithHTTPCode(404))
To fetch context information from error:
userMsg := UserMessage(err)
statusCode := HTTPCode(err)
stacktrace := Stacktrace(err)
To print full details of the error:
log.Printf("%v+", err) // or log.Println(merry.Details(err))
v1 -> v2
--------
v1 used a fluent API style which proved awkward in some cases. In general, fluent APIs
don't work that well in go, because they interfere with how interfaces are typically used to
compose with other packages. v2 uses a functional options API style which more easily
allows other packages to augment this one.
This also fixed bad smell with v1's APIs: they mostly returned a big, ugly `merry.Error` interface,
instead of plain `error` instances. v2 has a smaller, simpler API, which exclusively uses plain
errors.
v2 also implements a simpler and more robust integration with errors.Is/As/Unwrap. v2's functions will
work with error wrapper chains even if those chains contain errors not created with this package, so
long as those errors conform to the Unwrap() convention.
v2 allows more granular control over stacktraces: stack capture can be turned on or off on individual errors,
overriding the global setting. External stacktraces can be used as well.
v1 has been reimplemented in terms of v2, and the versions are completely compatible, and can be mixed.
Plugs
-----
- Check out my HTTP client library: [github.com/gemalto/requester](https://github.com/gemalto/requester)
- Check out my log library: [github.com/gemalto/flume](https://github.com/gemalto/flume)
License
-------
This package is licensed under the MIT license, see LICENSE.MIT for details.

88
vendor/github.com/ansel1/merry/v2/config.go generated vendored Normal file
View File

@ -0,0 +1,88 @@
package merry
import (
"sync"
)
var maxStackDepth = 50
var captureStacks = true
// StackCaptureEnabled returns whether stack capturing is enabled.
func StackCaptureEnabled() bool {
return captureStacks
}
// SetStackCaptureEnabled sets stack capturing globally. Disabling stack capture can increase performance.
// Capture can be forced or suppressed to override this global setting on a particular error.
func SetStackCaptureEnabled(enabled bool) {
captureStacks = enabled
}
// MaxStackDepth returns the number of frames captured in stacks.
func MaxStackDepth() int {
return maxStackDepth
}
// SetMaxStackDepth sets the MaxStackDepth.
func SetMaxStackDepth(depth int) {
maxStackDepth = depth
}
func init() {
RegisterDetail("User Message", errKeyUserMessage)
RegisterDetail("HTTP Code", errKeyHTTPCode)
}
var detailsLock sync.Mutex
var detailFields = map[string]func(err error) interface{}{}
// RegisterDetail registers an error property key in a global registry, with a label.
// See RegisterDetailFunc. This function just wraps a call to Value(key) and passes
// it to RegisterDetailFunc.
func RegisterDetail(label string, key interface{}) {
RegisterDetailFunc(label, func(err error) interface{} {
return Value(err, key)
})
}
// RegisterDetailFunc registers a label and a function for extracting a value from
// an error. When formatting errors produced by this package using the
// `%+v` placeholder, or when using Details(), these functions will be called
// on the error, and any non-nil values will be added to the text.
// For example:
//
// err := New("boom")
// err = err.WithValue(colorKey, "red")
// fmt.Println(Details(err))
//
// // Output:
// // boom
// //
// // <stacktrace>
//
// func Color(err) string {
// s, _ := Value(err, colorKey)
// return s
// }
//
// RegisterDetailFunc("color", Color)
// fmt.Println(Details(err))
//
// // Output:
// // boom
// // color: red
// //
// // <stacktrace>
//
// Error property keys are typically not exported by the packages which define them.
// Packages instead export functions which let callers access that property.
// It's therefore up to the package
// to register those properties which would make sense to include in the Details() output.
// In other words, it's up to the author of the package which generates the errors
// to publish printable error details, not the callers of the package.
func RegisterDetailFunc(label string, f func(err error) interface{}) {
detailsLock.Lock()
defer detailsLock.Unlock()
detailFields[label] = f
}

97
vendor/github.com/ansel1/merry/v2/doc.go generated vendored Normal file
View File

@ -0,0 +1,97 @@
// Package merry adds context to errors, including automatic stack capture, cause chains, HTTP status code, user
// messages, and arbitrary values.
//
// Wrapped errors work a lot like google's golang.org/x/net/context package:
// each wrapper error contains the inner error, a key, and a value.
// Like contexts, errors are immutable: adding a key/value to an error
// always creates a new error which wraps the original.
//
// This package comes with built-in support for adding information to errors:
//
// * stacktraces
// * changing the error message
// * HTTP status codes
// * End user error messages
// * causes
//
// You can also add your own additional information.
//
// The stack capturing feature can be turned off for better performance, though it's pretty fast. Benchmarks
// on an 2017 MacBook Pro, with go 1.10:
//
// BenchmarkNew_withStackCapture-8 2000000 749 ns/op
// BenchmarkNew_withoutStackCapture-8 20000000 64.1 ns/op
//
// Usage
//
// This package contains functions for creating errors, or wrapping existing errors. To create:
//
// err := New("boom!")
// err := Errorf("error fetching %s", filename)
//
// Additional context information can be attached to errors using functional options, called Wrappers:
//
// err := New("record not found", WithHTTPCode(404))
//
// Errorf() also accepts wrappers, mixed in with the format args:
//
// err := Errorf("user %s not found", username, WithHTTPCode(404))
//
// Wrappers can be applied to existing errors with Wrap():
//
// err = Wrap(err, WithHTTPCode(404))
//
// Wrap() will add a stacktrace to any error which doesn't already have one attached. WrapSkipping()
// can be used to control where the stacktrace starts.
//
// This package contains wrappers for adding specific context information to errors, such as an
// HTTPCode. You can create your own wrappers using the primitive Value(), WithValue(), and Set()
// functions.
//
// Errors produced by this package implement fmt.Formatter, to print additional information about the
// error:
//
// fmt.Printf("%v", err) // print error message and causes
// fmt.Printf("%s", err) // same as %s
// fmt.Printf("%q", err) // same as fmt.Printf("%q", err.Error())
// fmt.Printf("%v+", err) // print Details(err)
//
// Details() prints the error message, all causes, the stacktrace, and additional error
// values configured with RegisterDetailFunc(). By default, it will show the HTTP status
// code and user message.
//
// Stacktraces
//
// By default, any error created by or wrapped by this package will automatically have
// a stacktrace captured and attached to the error. This capture only happens if the
// error doesn't already have a stack attached to it, so wrapping the error with additional
// context won't capture additional stacks.
//
// When and how stacks are captured can be customized. SetMaxStackDepth() can globally configure
// how many frames to capture. SetStackCaptureEnabled() can globally configure whether
// stacks are captured by default.
//
// Wrap(err, NoStackCapture()) can be used to selectively suppress stack capture for a particular
// error.
//
// Wrap(err, CaptureStack(false)) will capture a new stack at the Wrap call site, even if the err
// already had an earlier stack attached. The new stack overrides the older stack.
//
// Wrap(err, CaptureStack(true)) will force a stack capture at the call site even if stack
// capture is disabled globally.
//
// Finally, Wrappers are passed a depth argument so they know how deep they are in the call stack
// from the call site where this package's API was called. This allows Wrappers to implement their
// own stack capturing logic.
//
// The package contains functions for creating new errors with stacks, or adding a stack to `error`
// instances. Functions with add context (e.g. `WithValue()`) work on any `error`, and will
// automatically convert them to merry errors (with a stack) if necessary.
//
// Hooks
//
// AddHooks() can install wrappers which are applied to all errors processed by this package. Hooks
// are applied before any other wrappers or processing takes place. They can be used to integrate
// with errors from other packages, normalizing errors (such as applying standard status codes to
// application errors), localizing user messages, or replacing the stack capturing mechanism.
package merry

334
vendor/github.com/ansel1/merry/v2/errors.go generated vendored Normal file
View File

@ -0,0 +1,334 @@
package merry
import (
"errors"
"fmt"
"runtime"
)
// New creates a new error, with a stack attached. The equivalent of golang's errors.New()
func New(msg string, wrappers ...Wrapper) error {
return WrapSkipping(errors.New(msg), 1, wrappers...)
}
// Errorf creates a new error with a formatted message and a stack. The equivalent of golang's fmt.Errorf().
// args may contain either arguments to format, or Wrapper options, which will be applied to the error.
func Errorf(format string, args ...interface{}) error {
fmtArgs, wrappers := splitWrappers(args)
return WrapSkipping(fmt.Errorf(format, fmtArgs...), 1, wrappers...)
}
// Sentinel creates an error without running hooks or capturing a stack. It is intended
// to create sentinel errors, which will be wrapped with a stack later from where the
// error is returned. At that time, a stack will be captured and hooks will be run.
//
// var ErrNotFound = merry.Sentinel("not found", merry.WithHTTPCode(404))
//
// func FindUser(name string) (*User, error) {
// // some db code which fails to find a user
// return nil, merry.Wrap(ErrNotFound)
// }
//
// func main() {
// _, err := FindUser("bob")
// fmt.Println(errors.Is(err, ErrNotFound) // "true"
// fmt.Println(merry.Details(err)) // stacktrace will start at the return statement
// // in FindUser()
// }
func Sentinel(msg string, wrappers ...Wrapper) error {
return ApplySkipping(errors.New(msg), 1, wrappers...)
}
// Sentinelf is like Sentinel, but takes a formatted message. args can be a mix of
// format arguments and Wrappers.
func Sentinelf(format string, args ...interface{}) error {
fmtArgs, wrappers := splitWrappers(args)
return ApplySkipping(fmt.Errorf(format, fmtArgs...), 1, wrappers...)
}
func splitWrappers(args []interface{}) ([]interface{}, []Wrapper) {
var wrappers []Wrapper
// pull out the args which are wrappers
n := 0
for _, arg := range args {
if w, ok := arg.(Wrapper); ok {
wrappers = append(wrappers, w)
} else {
args[n] = arg
n++
}
}
args = args[:n]
return args, wrappers
}
// Wrap adds context to errors by applying Wrappers. See WithXXX() functions for Wrappers supplied
// by this package.
//
// If StackCaptureEnabled is true, a stack starting at the caller will be automatically captured
// and attached to the error. This behavior can be overridden with wrappers which either capture
// their own stacks, or suppress auto capture.
//
// If err is nil, returns nil.
func Wrap(err error, wrappers ...Wrapper) error {
return WrapSkipping(err, 1, wrappers...)
}
// WrapSkipping is like Wrap, but the captured stacks will start `skip` frames
// further up the call stack. If skip is 0, it behaves the same as Wrap.
func WrapSkipping(err error, skip int, wrappers ...Wrapper) error {
if err == nil {
return nil
}
if len(onceHooks) > 0 {
if _, ok := Lookup(err, errKeyHooked); !ok {
err = ApplySkipping(err, skip+1, onceHooks...)
err = ApplySkipping(err, skip+1, WithValue(errKeyHooked, err))
}
}
err = ApplySkipping(err, skip+1, hooks...)
err = ApplySkipping(err, skip+1, wrappers...)
return captureStack(err, skip+1, false)
}
// Apply is like Wrap, but does not execute hooks or do automatic stack capture. It just
// applies the wrappers to the error.
func Apply(err error, wrappers ...Wrapper) error {
return ApplySkipping(err, 1, wrappers...)
}
// ApplySkipping is like WrapSkipping, but does not execute hooks or do automatic stack capture. It just
// applies the wrappers to the error. It is useful in Wrapper implementations which
// // want to apply other Wrappers without starting an infinite recursion.
func ApplySkipping(err error, skip int, wrappers ...Wrapper) error {
if err == nil {
return nil
}
for _, w := range wrappers {
err = w.Wrap(err, skip+1)
}
return err
}
// Prepend is a convenience function for the PrependMessage wrapper. It eases migration
// from merry v1. It accepts a varargs of additional Wrappers.
func Prepend(err error, msg string, wrappers ...Wrapper) error {
return WrapSkipping(err, 1, append(wrappers, PrependMessage(msg))...)
}
// Prependf is a convenience function for the PrependMessagef wrapper. It eases migration
// from merry v1. The args can be format arguments mixed with Wrappers.
func Prependf(err error, format string, args ...interface{}) error {
fmtArgs, wrappers := splitWrappers(args)
return WrapSkipping(err, 1, append(wrappers, PrependMessagef(format, fmtArgs...))...)
}
// Append is a convenience function for the AppendMessage wrapper. It eases migration
// from merry v1. It accepts a varargs of additional Wrappers.
func Append(err error, msg string, wrappers ...Wrapper) error {
return WrapSkipping(err, 1, append(wrappers, AppendMessage(msg))...)
}
// Appendf is a convenience function for the AppendMessagef wrapper. It eases migration
// from merry v1. The args can be format arguments mixed with Wrappers.
func Appendf(err error, format string, args ...interface{}) error {
fmtArgs, wrappers := splitWrappers(args)
return WrapSkipping(err, 1, append(wrappers, AppendMessagef(format, fmtArgs...))...)
}
// Value returns the value for key, or nil if not set.
// If e is nil, returns nil. Will not search causes.
func Value(err error, key interface{}) interface{} {
v, _ := Lookup(err, key)
return v
}
// Lookup returns the value for the key, and a boolean indicating
// whether the value was set. Will not search causes.
//
// if err is nil, returns nil and false.
func Lookup(err error, key interface{}) (interface{}, bool) {
var merr interface {
error
isMerryError()
}
// I've tried implementing this logic a few different ways. It's tricky:
//
// - Lookup should only search the current error, but not causes. errWithCause's
// Unwrap() will eventually unwrap to the cause, so we don't want to just
// search the entire stream of errors returned by Unwrap.
// - We need to handle cases where error implementations created outside
// this package are in the middle of the chain. We need to use Unwrap
// in these cases to traverse those errors and dig down to the next
// merry error.
// - Some error packages, including our own, do funky stuff with Unwrap(),
// returning shim types to control the unwrapping order, rather than
// the actual, raw wrapped error. Typically, these shims implement
// Is/As to delegate to the raw error they encapsulate, but implement
// Unwrap by encapsulating the raw error in another shim. So if we're looking
// for a raw error type, we can't just use Unwrap() and do type assertions
// against the result. We have to use errors.As(), to allow the shims to delegate
// the type assertion to the raw error correctly.
//
// Based on all these constraints, we use errors.As() with an internal interface
// that can only be implemented by our internal error types. When one is found,
// we handle each of our internal types as a special case. For errWithCause, we
// traverse to the wrapped error, ignoring the cause and the funky Unwrap logic.
// We could have just used errors.As(err, *errWithValue), but that would have
// traversed into the causes.
for {
switch t := err.(type) {
case *errWithValue:
if t.key == key {
return t.value, true
}
err = t.err
case *errWithCause:
err = t.err
default:
if errors.As(err, &merr) {
err = merr
} else {
return nil, false
}
}
}
}
// Values returns a map of all values attached to the error
// If a key has been attached multiple times, the map will
// contain the last value mapped
// If e is nil, returns nil.
func Values(err error) map[interface{}]interface{} {
var values map[interface{}]interface{}
for err != nil {
if e, ok := err.(*errWithValue); ok {
if _, ok := values[e.key]; !ok {
if values == nil {
values = map[interface{}]interface{}{}
}
values[e.key] = e.value
}
}
err = errors.Unwrap(err)
}
return values
}
// Stack returns the stack attached to an error, or nil if one is not attached
// If e is nil, returns nil.
func Stack(err error) []uintptr {
stack, _ := Value(err, errKeyStack).([]uintptr)
return stack
}
// HTTPCode converts an error to an http status code. All errors
// map to 500, unless the error has an http code attached.
// If e is nil, returns 200.
func HTTPCode(err error) int {
if err == nil {
return 200
}
code, _ := Value(err, errKeyHTTPCode).(int)
if code == 0 {
return 500
}
return code
}
// UserMessage returns the end-user safe message. Returns empty if not set.
// If e is nil, returns "".
func UserMessage(err error) string {
msg, _ := Value(err, errKeyUserMessage).(string)
return msg
}
// Cause returns the cause of the argument. If e is nil, or has no cause,
// nil is returned.
func Cause(err error) error {
var causer *errWithCause
if errors.As(err, &causer) {
return causer.cause
}
return nil
}
// RegisteredDetails extracts details registered with RegisterDetailFunc from an error, and
// returns them as a map. Values may be nil.
//
// If err is nil or there are no registered details, nil is returned.
func RegisteredDetails(err error) map[string]interface{} {
detailsLock.Lock()
defer detailsLock.Unlock()
if len(detailFields) == 0 || err == nil {
return nil
}
dets := map[string]interface{}{}
for label, f := range detailFields {
dets[label] = f(err)
}
return dets
}
// captureStack: return an error with a stack attached. Stack will skip
// specified frames. skip = 0 will start at caller.
// If the err already has a stack, to auto-stack-capture is disabled globally,
// this is a no-op. Use force to override and force a stack capture
// in all cases.
func captureStack(err error, skip int, force bool) error {
if err == nil {
return nil
}
var c interface {
Callers() []uintptr
}
switch {
case force:
// always capture
case HasStack(err):
return err
case errors.As(err, &c):
// if the go-errors already captured a stack
// reuse it
if stack := c.Callers(); len(stack) > 0 {
return Set(err, errKeyStack, stack)
}
case !captureStacks:
return err
}
s := make([]uintptr, MaxStackDepth())
length := runtime.Callers(2+skip, s[:])
return Set(err, errKeyStack, s[:length])
}
// HasStack returns true if a stack is already attached to the err.
// If err == nil, returns false.
//
// If a stack capture was suppressed with NoCaptureStack(), this will
// still return true, indicating that stack capture processing has already
// occurred on this error.
func HasStack(err error) bool {
_, ok := Lookup(err, errKeyStack)
return ok
}

37
vendor/github.com/ansel1/merry/v2/hooks.go generated vendored Normal file
View File

@ -0,0 +1,37 @@
package merry
var hooks []Wrapper
var onceHooks []Wrapper
// AddHooks installs a global set of Wrappers which are applied to every error processed
// by this package. They are applied before any other Wrappers or stack capturing are
// applied. Hooks can add additional wrappers to errors, or translate annotations added
// by other error libraries into merry annotations.
//
// Note that these hooks will be applied each time an err is passed to Wrap/Apply. If you
// only want your hook to run once per error, see AddOnceHooks.
//
// This function is not thread safe, and should only be called very early in program
// initialization.
func AddHooks(hook ...Wrapper) {
hooks = append(hooks, hook...)
}
// AddOnceHooks is like AddHooks, but these hooks will only be applied once per error.
// Once hooks are applied to an error, the error is marked, and future Wrap/Apply calls
// on the error will not apply these hooks again.
//
// This function is not thread safe, and should only be called very early in program
// initialization.
func AddOnceHooks(hook ...Wrapper) {
onceHooks = append(onceHooks, hook...)
}
// ClearHooks removes all installed hooks.
//
// This function is not thread safe, and should only be called very early in program
// initialization.
func ClearHooks() {
hooks = nil
onceHooks = nil
}

167
vendor/github.com/ansel1/merry/v2/impl.go generated vendored Normal file
View File

@ -0,0 +1,167 @@
package merry
import (
"errors"
"fmt"
"reflect"
)
type errKey int
const (
errKeyNone errKey = iota
errKeyStack
errKeyMessage
errKeyHTTPCode
errKeyUserMessage
errKeyForceCapture
errKeyHooked
)
func (e errKey) String() string {
switch e {
case errKeyNone:
return "none"
case errKeyStack:
return "stack"
case errKeyMessage:
return "message"
case errKeyHTTPCode:
return "http status code"
case errKeyUserMessage:
return "user message"
case errKeyForceCapture:
return "force stack capture"
default:
return ""
}
}
type errWithValue struct {
err error
key, value interface{}
}
// Format implements fmt.Formatter
func (e *errWithValue) Format(s fmt.State, verb rune) {
Format(s, verb, e)
}
// Error implements golang's error interface
// returns the message value if set, otherwise
// delegates to inner error
func (e *errWithValue) Error() string {
if e.key == errKeyMessage {
if s, ok := e.value.(string); ok {
return s
}
}
return e.err.Error()
}
// String implements fmt.Stringer
func (e *errWithValue) String() string {
return e.Error()
}
// Unwrap returns the next wrapped error.
func (e *errWithValue) Unwrap() error {
return e.err
}
// isMerryError is a marker method for identifying error types implemented by this package.
func (e *errWithValue) isMerryError() {}
type errWithCause struct {
err error
cause error
}
func (e *errWithCause) Unwrap() error {
// skip through any directly nested errWithCauses.
// our implementation of Is/As already recursed through them,
// so we want to dig down to the first non-errWithCause.
nextErr := e.err
for {
if e, ok := nextErr.(*errWithCause); ok {
nextErr = e.err
} else {
break
}
}
// errWithCause.Is/As() also already checked nextErr, so we want to
// unwrap it and get to the next error down.
nextErr = errors.Unwrap(nextErr)
// we've reached the end of this wrapper chain. Return the cause.
if nextErr == nil {
return e.cause
}
// return a new errWithCause wrapper, wrapping next error, but bundling
// it will our cause, ignoring the causes of the errWithCauses we skip
// over above. This is how we carry the latest cause along as we unwrap
// the chain. When we get to the end of the chain, we'll return this latest
// cause.
return &errWithCause{err: nextErr, cause: e.cause}
}
func (e *errWithCause) String() string {
return e.Error()
}
func (e *errWithCause) Error() string {
return e.err.Error()
}
func (e *errWithCause) Format(f fmt.State, verb rune) {
Format(f, verb, e)
}
// errWithCause needs to provide custome implementations of Is and As.
// errors.Is() doesn't work on errWithCause because error.Is() uses errors.Unwrap() to traverse the error
// chain. But errWithCause.Unwrap() doesn't return the next error in the chain. Instead,
// it wraps the next error in a shim. The standard Is/As tests would compare the shim to the target.
// We need to override Is/As to compare the target to the error inside the shim.
func (e *errWithCause) Is(target error) bool {
// This does most of what errors.Is() does, by delegating
// to the nested error. But it does not use Unwrap to recurse
// any further. This just compares target with next error in the stack.
isComparable := reflect.TypeOf(target).Comparable()
if isComparable && e.err == target {
return true
}
// since errWithCause implements Is(), this will effectively recurse through
// any directly nested errWithCauses.
if x, ok := e.err.(interface{ Is(error) bool }); ok && x.Is(target) {
return true
}
return false
}
func (e *errWithCause) As(target interface{}) bool {
// This does most of what errors.As() does, by delegating
// to the nested error. But it does not use Unwrap to recurse
// any further. This just compares target with next error in the stack.
val := reflect.ValueOf(target)
typ := val.Type()
targetType := typ.Elem()
if reflect.TypeOf(e.err).AssignableTo(targetType) {
val.Elem().Set(reflect.ValueOf(e.err))
return true
}
// since errWithCause implements As(), this will effectively recurse through
// any directly nested errWithCauses.
if x, ok := e.err.(interface{ As(interface{}) bool }); ok && x.As(target) {
return true
}
return false
}
// isMerryError is a marker method for identifying error types implemented by this package.
func (e *errWithCause) isMerryError() {}

144
vendor/github.com/ansel1/merry/v2/print.go generated vendored Normal file
View File

@ -0,0 +1,144 @@
package merry
import (
"fmt"
"io"
"path"
"runtime"
"sort"
"strings"
)
// Location returns zero values if e has no stacktrace
func Location(err error) (file string, line int) {
s := Stack(err)
if len(s) > 0 {
fnc, _ := runtime.CallersFrames(s[:1]).Next()
return fnc.File, fnc.Line
}
return "", 0
}
// SourceLine returns the string representation of
// Location's result or an empty string if there's
// no stracktrace.
func SourceLine(err error) string {
s := Stack(err)
if len(s) > 0 {
fnc, _ := runtime.CallersFrames(s[:1]).Next()
_, f := path.Split(fnc.File)
return fmt.Sprintf("%s (%s:%d)", fnc.Function, f, fnc.Line)
}
return ""
}
// FormattedStack returns the stack attached to an error, formatted as a slice of strings.
// Each string represents a frame in the stack, newest first. The strings may
// have internal newlines.
//
// Returns nil if no formatted stack and no stack is associated, or err is nil.
func FormattedStack(err error) []string {
formattedStack, _ := Value(err, errKeyStack).([]string)
if len(formattedStack) > 0 {
return formattedStack
}
s := Stack(err)
if len(s) > 0 {
lines := make([]string, 0, len(s))
frames := runtime.CallersFrames(s)
for {
frame, more := frames.Next()
lines = append(lines, fmt.Sprintf("%s\n\t%s:%d", frame.Function, frame.File, frame.Line))
if !more {
break
}
}
return lines
}
return nil
}
// Stacktrace returns the error's stacktrace as a string formatted.
// If e has no stacktrace, returns an empty string.
func Stacktrace(err error) string {
return strings.Join(FormattedStack(err), "\n")
}
// Details returns e.Error(), e's stacktrace, and any additional details which have
// be registered with RegisterDetail. User message and HTTP code are already registered.
//
// The details of each error in e's cause chain will also be printed.
func Details(e error) string {
if e == nil {
return ""
}
msg := e.Error()
var dets []string
detailsLock.Lock()
for label, f := range detailFields {
v := f(e)
if v != nil {
dets = append(dets, fmt.Sprintf("%s: %v", label, v))
}
}
detailsLock.Unlock()
if len(dets) > 0 {
// sort so output is predictable
sort.Strings(dets)
msg += "\n" + strings.Join(dets, "\n")
}
s := Stacktrace(e)
if s != "" {
msg += "\n\n" + s
}
if c := Cause(e); c != nil {
msg += "\n\nCaused By: " + Details(c)
}
return msg
}
// Format adapts errors to fmt.Formatter interface. It's intended to be used
// help error impls implement fmt.Formatter, e.g.:
//
// func (e *myErr) Format(f fmt.State, verb rune) {
// Format(f, verb, e)
// }
//
func Format(s fmt.State, verb rune, err error) {
switch verb {
case 'v':
if s.Flag('+') {
io.WriteString(s, Details(err))
return
}
fallthrough
case 's':
io.WriteString(s, msgWithCauses(err))
case 'q':
fmt.Fprintf(s, "%q", err.Error())
}
}
func msgWithCauses(err error) string {
messages := make([]string, 0, 5)
for err != nil {
if ce := err.Error(); ce != "" {
messages = append(messages, ce)
}
err = Cause(err)
}
return strings.Join(messages, ": ")
}

183
vendor/github.com/ansel1/merry/v2/wrappers.go generated vendored Normal file
View File

@ -0,0 +1,183 @@
package merry
import "fmt"
// Wrapper knows how to wrap errors with context information.
type Wrapper interface {
// Wrap returns a new error, wrapping the argument, and typically adding some context information.
// skipCallers is how many callers to skip when capturing a stack to skip to the caller of the merry
// API surface. It's intended to make it possible to write wrappers which capture stacktraces. e.g.
//
// func CaptureStack() Wrapper {
// return WrapperFunc(func(err error, skipCallers int) error {
// s := make([]uintptr, 50)
// // Callers
// l := runtime.Callers(2+skipCallers, s[:])
// return WithStack(s[:l]).Wrap(err, skipCallers + 1)
// })
// }
Wrap(err error, skipCallers int) error
}
// WrapperFunc implements Wrapper.
type WrapperFunc func(error, int) error
// Wrap implements the Wrapper interface.
func (w WrapperFunc) Wrap(err error, callerDepth int) error {
return w(err, callerDepth+1)
}
// WithValue associates a key/value pair with an error.
func WithValue(key, value interface{}) Wrapper {
return WrapperFunc(func(err error, _ int) error {
return Set(err, key, value)
})
}
// WithMessage overrides the value returned by err.Error().
func WithMessage(msg string) Wrapper {
return WithValue(errKeyMessage, msg)
}
// WithMessagef overrides the value returned by err.Error().
func WithMessagef(format string, args ...interface{}) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyMessage, fmt.Sprintf(format, args...))
})
}
// WithUserMessage associates an end-user message with an error.
func WithUserMessage(msg string) Wrapper {
return WithValue(errKeyUserMessage, msg)
}
// WithUserMessagef associates a formatted end-user message with an error.
func WithUserMessagef(format string, args ...interface{}) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyUserMessage, fmt.Sprintf(format, args...))
})
}
// AppendMessage a message after the current error message, in the format "original: new".
func AppendMessage(msg string) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyMessage, err.Error()+": "+msg)
})
}
// AppendMessagef is the same as AppendMessage, but with a formatted message.
func AppendMessagef(format string, args ...interface{}) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyMessage, err.Error()+": "+fmt.Sprintf(format, args...))
})
}
// PrependMessage a message before the current error message, in the format "new: original".
func PrependMessage(msg string) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyMessage, msg+": "+err.Error())
})
}
// PrependMessagef is the same as PrependMessage, but with a formatted message.
func PrependMessagef(format string, args ...interface{}) Wrapper {
return WrapperFunc(func(err error, _ int) error {
if err == nil {
return nil
}
return Set(err, errKeyMessage, fmt.Sprintf(format, args...)+": "+err.Error())
})
}
// WithHTTPCode associates an HTTP status code with an error.
func WithHTTPCode(statusCode int) Wrapper {
return WithValue(errKeyHTTPCode, statusCode)
}
// WithStack associates a stack of caller frames with an error. Generally, this package
// will automatically capture and associate a stack with errors which are created or
// wrapped by this package. But this allows the caller to associate an externally
// generated stack.
func WithStack(stack []uintptr) Wrapper {
return WithValue(errKeyStack, stack)
}
// WithFormattedStack associates a stack of pre-formatted strings describing frames of a
// stacktrace. Generally, a formatted stack is generated from the raw []uintptr stack
// associated with the error, but a pre-formatted stack can be associated with the error
// instead, and takes precedence over the raw stack. This is useful if pre-formatted
// stack information is coming from some other source.
func WithFormattedStack(stack []string) Wrapper {
return WithValue(errKeyStack, stack)
}
// NoCaptureStack will suppress capturing a stack, even if StackCaptureEnabled() == true.
func NoCaptureStack() Wrapper {
return WrapperFunc(func(err error, _ int) error {
// if this err already has a stack set, there is no need to set the
// stack property again, and we don't want to override the prior the stack
if HasStack(err) {
return err
}
return Set(err, errKeyStack, nil)
})
}
// CaptureStack will override an earlier stack with a stack captured from the current
// call site. If StackCaptureEnabled() == false, this is a no-op.
//
// If force is set, StackCaptureEnabled() will be ignored: a stack will always be captured.
func CaptureStack(force bool) Wrapper {
return WrapperFunc(func(err error, callerDepth int) error {
return captureStack(err, callerDepth+1, force || StackCaptureEnabled())
})
}
// WithCause sets one error as the cause of another error. This is useful for associating errors
// from lower API levels with sentinel errors in higher API levels. errors.Is() and errors.As()
// will traverse both the main chain of error wrappers, as well as down the chain of causes.
func WithCause(err error) Wrapper {
return WrapperFunc(func(nerr error, _ int) error {
if nerr == nil {
return nil
}
return &errWithCause{err: nerr, cause: err}
})
}
// Set wraps an error with a key/value pair. This is the simplest form of associating
// a value with an error. It does not capture a stacktrace, invoke hooks, or do any
// other processing. It is mainly intended as a primitive for writing Wrapper implementations.
//
// if err is nil, returns nil.
//
// Keeping this private for now. If it proves useful, it may be made public later, but
// for now, external packages can get the same behavor with this:
//
// WithValue(key, value).Wrap(err)
//
func Set(err error, key, value interface{}) error {
if err == nil {
return nil
}
return &errWithValue{
err: err,
key: key,
value: value,
}
}