forked from TrueCloudLab/rclone
backend/tardigrade: Upgrade to uplink v1.1.1
This fixes issue #4370 by restoring the correct error response.
This commit is contained in:
parent
a55d882b7b
commit
e780cda1d4
125 changed files with 14632 additions and 92919 deletions
6
vendor/github.com/spacemonkeygo/errors/.travis.yml
generated
vendored
6
vendor/github.com/spacemonkeygo/errors/.travis.yml
generated
vendored
|
@ -1,6 +0,0 @@
|
|||
language: go
|
||||
|
||||
go:
|
||||
- 1.7
|
||||
- 1.8
|
||||
- tip
|
191
vendor/github.com/spacemonkeygo/errors/LICENSE
generated
vendored
191
vendor/github.com/spacemonkeygo/errors/LICENSE
generated
vendored
|
@ -1,191 +0,0 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction, and
|
||||
distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by the copyright
|
||||
owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all other entities
|
||||
that control, are controlled by, or are under common control with that entity.
|
||||
For the purposes of this definition, "control" means (i) the power, direct or
|
||||
indirect, to cause the direction or management of such entity, whether by
|
||||
contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity exercising
|
||||
permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications, including
|
||||
but not limited to software source code, documentation source, and configuration
|
||||
files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical transformation or
|
||||
translation of a Source form, including but not limited to compiled object code,
|
||||
generated documentation, and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or Object form, made
|
||||
available under the License, as indicated by a copyright notice that is included
|
||||
in or attached to the work (an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object form, that
|
||||
is based on (or derived from) the Work and for which the editorial revisions,
|
||||
annotations, elaborations, or other modifications represent, as a whole, an
|
||||
original work of authorship. For the purposes of this License, Derivative Works
|
||||
shall not include works that remain separable from, or merely link (or bind by
|
||||
name) to the interfaces of, the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including the original version
|
||||
of the Work and any modifications or additions to that Work or Derivative Works
|
||||
thereof, that is intentionally submitted to Licensor for inclusion in the Work
|
||||
by the copyright owner or by an individual or Legal Entity authorized to submit
|
||||
on behalf of the copyright owner. For the purposes of this definition,
|
||||
"submitted" means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems, and
|
||||
issue tracking systems that are managed by, or on behalf of, the Licensor for
|
||||
the purpose of discussing and improving the Work, but excluding communication
|
||||
that is conspicuously marked or otherwise designated in writing by the copyright
|
||||
owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf
|
||||
of whom a Contribution has been received by Licensor and subsequently
|
||||
incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the Work and such
|
||||
Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License.
|
||||
|
||||
Subject to the terms and conditions of this License, each Contributor hereby
|
||||
grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free,
|
||||
irrevocable (except as stated in this section) patent license to make, have
|
||||
made, use, offer to sell, sell, import, and otherwise transfer the Work, where
|
||||
such license applies only to those patent claims licensable by such Contributor
|
||||
that are necessarily infringed by their Contribution(s) alone or by combination
|
||||
of their Contribution(s) with the Work to which such Contribution(s) was
|
||||
submitted. If You institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work or a
|
||||
Contribution incorporated within the Work constitutes direct or contributory
|
||||
patent infringement, then any patent licenses granted to You under this License
|
||||
for that Work shall terminate as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution.
|
||||
|
||||
You may reproduce and distribute copies of the Work or Derivative Works thereof
|
||||
in any medium, with or without modifications, and in Source or Object form,
|
||||
provided that You meet the following conditions:
|
||||
|
||||
You must give any other recipients of the Work or Derivative Works a copy of
|
||||
this License; and
|
||||
You must cause any modified files to carry prominent notices stating that You
|
||||
changed the files; and
|
||||
You must retain, in the Source form of any Derivative Works that You distribute,
|
||||
all copyright, patent, trademark, and attribution notices from the Source form
|
||||
of the Work, excluding those notices that do not pertain to any part of the
|
||||
Derivative Works; and
|
||||
If the Work includes a "NOTICE" text file as part of its distribution, then any
|
||||
Derivative Works that You distribute must include a readable copy of the
|
||||
attribution notices contained within such NOTICE file, excluding those notices
|
||||
that do not pertain to any part of the Derivative Works, in at least one of the
|
||||
following places: within a NOTICE text file distributed as part of the
|
||||
Derivative Works; within the Source form or documentation, if provided along
|
||||
with the Derivative Works; or, within a display generated by the Derivative
|
||||
Works, if and wherever such third-party notices normally appear. The contents of
|
||||
the NOTICE file are for informational purposes only and do not modify the
|
||||
License. You may add Your own attribution notices within Derivative Works that
|
||||
You distribute, alongside or as an addendum to the NOTICE text from the Work,
|
||||
provided that such additional attribution notices cannot be construed as
|
||||
modifying the License.
|
||||
You may add Your own copyright statement to Your modifications and may provide
|
||||
additional or different license terms and conditions for use, reproduction, or
|
||||
distribution of Your modifications, or for any such Derivative Works as a whole,
|
||||
provided Your use, reproduction, and distribution of the Work otherwise complies
|
||||
with the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions.
|
||||
|
||||
Unless You explicitly state otherwise, any Contribution intentionally submitted
|
||||
for inclusion in the Work by You to the Licensor shall be under the terms and
|
||||
conditions of this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify the terms of
|
||||
any separate license agreement you may have executed with Licensor regarding
|
||||
such Contributions.
|
||||
|
||||
6. Trademarks.
|
||||
|
||||
This License does not grant permission to use the trade names, trademarks,
|
||||
service marks, or product names of the Licensor, except as required for
|
||||
reasonable and customary use in describing the origin of the Work and
|
||||
reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty.
|
||||
|
||||
Unless required by applicable law or agreed to in writing, Licensor provides the
|
||||
Work (and each Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied,
|
||||
including, without limitation, any warranties or conditions of TITLE,
|
||||
NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are
|
||||
solely responsible for determining the appropriateness of using or
|
||||
redistributing the Work and assume any risks associated with Your exercise of
|
||||
permissions under this License.
|
||||
|
||||
8. Limitation of Liability.
|
||||
|
||||
In no event and under no legal theory, whether in tort (including negligence),
|
||||
contract, or otherwise, unless required by applicable law (such as deliberate
|
||||
and grossly negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special, incidental,
|
||||
or consequential damages of any character arising as a result of this License or
|
||||
out of the use or inability to use the Work (including but not limited to
|
||||
damages for loss of goodwill, work stoppage, computer failure or malfunction, or
|
||||
any and all other commercial damages or losses), even if such Contributor has
|
||||
been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability.
|
||||
|
||||
While redistributing the Work or Derivative Works thereof, You may choose to
|
||||
offer, and charge a fee for, acceptance of support, warranty, indemnity, or
|
||||
other liability obligations and/or rights consistent with this License. However,
|
||||
in accepting such obligations, You may act only on Your own behalf and on Your
|
||||
sole responsibility, not on behalf of any other Contributor, and only if You
|
||||
agree to indemnify, defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason of your
|
||||
accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work
|
||||
|
||||
To apply the Apache License to your work, attach the following boilerplate
|
||||
notice, with the fields enclosed by brackets "[]" replaced with your own
|
||||
identifying information. (Don't include the brackets!) The text should be
|
||||
enclosed in the appropriate comment syntax for the file format. We also
|
||||
recommend that a file or class name and description of purpose be included on
|
||||
the same "printed page" as the copyright notice for easier identification within
|
||||
third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
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.
|
19
vendor/github.com/spacemonkeygo/errors/README.md
generated
vendored
19
vendor/github.com/spacemonkeygo/errors/README.md
generated
vendored
|
@ -1,19 +0,0 @@
|
|||
# errors [](https://travis-ci.org/spacemonkeygo/errors)
|
||||
|
||||
Please see http://godoc.org/github.com/spacemonkeygo/errors for info
|
||||
|
||||
### License
|
||||
|
||||
Copyright (C) 2014 Space Monkey, Inc.
|
||||
|
||||
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.
|
24
vendor/github.com/spacemonkeygo/errors/config.go
generated
vendored
24
vendor/github.com/spacemonkeygo/errors/config.go
generated
vendored
|
@ -1,24 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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 errors
|
||||
|
||||
// Config is a configuration struct meant to be used with
|
||||
// github.com/spacemonkeygo/flagfile/utils.Setup
|
||||
// but can be set independently.
|
||||
var Config = struct {
|
||||
Stacklogsize int `default:"4096" usage:"the max stack trace byte length to log"`
|
||||
}{
|
||||
Stacklogsize: 4096,
|
||||
}
|
30
vendor/github.com/spacemonkeygo/errors/ctx17.go
generated
vendored
30
vendor/github.com/spacemonkeygo/errors/ctx17.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
// Copyright (C) 2016 Space Monkey, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build go1.7
|
||||
|
||||
// TODO: remove this build restriction once appengine supports 1.7
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
var (
|
||||
contextCanceled = context.Canceled
|
||||
contextDeadlineExceeded = context.DeadlineExceeded
|
||||
)
|
32
vendor/github.com/spacemonkeygo/errors/data_keys.go
generated
vendored
32
vendor/github.com/spacemonkeygo/errors/data_keys.go
generated
vendored
|
@ -1,32 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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 errors
|
||||
|
||||
import (
|
||||
"sync/atomic"
|
||||
)
|
||||
|
||||
var (
|
||||
lastId int32 = 0
|
||||
)
|
||||
|
||||
// DataKey's job is to make sure that keys in each error instances namespace
|
||||
// are lexically scoped, thus helping developers not step on each others' toes
|
||||
// between large packages. You can only store data on an error using a DataKey,
|
||||
// and you can only make DataKeys with GenSym().
|
||||
type DataKey struct{ id int32 }
|
||||
|
||||
// GenSym generates a brand new, never-before-seen DataKey
|
||||
func GenSym() DataKey { return DataKey{id: atomic.AddInt32(&lastId, 1)} }
|
205
vendor/github.com/spacemonkeygo/errors/doc.go
generated
vendored
205
vendor/github.com/spacemonkeygo/errors/doc.go
generated
vendored
|
@ -1,205 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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 errors is a flexible error support library for Go
|
||||
|
||||
Motivation
|
||||
|
||||
Go's standard library is intentionally sparse on providing error utilities, and
|
||||
developers coming from other programming languages may miss some features they
|
||||
took for granted [1]. This package is an attempt at providing those features in
|
||||
an idiomatic Go way.
|
||||
|
||||
The main features this package provides (in addition to miscellaneous
|
||||
utilities) are:
|
||||
|
||||
* Error hierarchies
|
||||
* Stack traces
|
||||
* Arbitrary error values
|
||||
|
||||
Error hierarchies
|
||||
|
||||
While Go has very deliberately not implemented class hierarchies, a quick
|
||||
perusal of Go's net and os packages should indicate that sometimes error
|
||||
hierarchies are useful. Go programmers should be familiar with the net.Error
|
||||
interface (and the types that fulfill it) as well as the os helper functions
|
||||
such as os.IsNotExist, os.IsPermission, etc.
|
||||
|
||||
Unfortunately, to implement something similar, a developer will have to
|
||||
implement a struct that matches the error interface as well as any testing
|
||||
methods or any more detailed interfaces they may choose to export. It's not
|
||||
hard, but it is friction, and developers tend to use fmt.Errorf instead due
|
||||
to ease of use, thus missing out on useful features that functions like
|
||||
os.IsNotExist and friends provide.
|
||||
|
||||
The errors package provides reusable components for building similar
|
||||
features while reducing friction as much as possible. With the errors package,
|
||||
the os error handling routines can be mimicked as follows:
|
||||
|
||||
package osmimic
|
||||
|
||||
import (
|
||||
"github.com/spacemonkeygo/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
OSError = errors.NewClass("OS Error")
|
||||
NotExist = OSError.NewClass("Not Exist")
|
||||
)
|
||||
|
||||
func Open(path string) (*File, error) {
|
||||
// actually do something here
|
||||
return nil, NotExist.New("path %#v doesn't exist", path)
|
||||
}
|
||||
|
||||
func MyMethod() error {
|
||||
fh, err := Open(mypath)
|
||||
if err != nil {
|
||||
if NotExist.Contains(err) {
|
||||
// file doesn't exist, do stuff
|
||||
}
|
||||
return err
|
||||
}
|
||||
// do stuff
|
||||
}
|
||||
|
||||
Stack traces
|
||||
|
||||
It doesn't take long during Go development before you may find yourself
|
||||
wondering where an error came from. In other languages, as soon as an error is
|
||||
raised, a stack trace is captured and is displayed as part of the language's
|
||||
error handling. Go error types are simply basic values and no such magic
|
||||
happens to tell you what line or what stack an error came from.
|
||||
|
||||
The errors package fixes this by optionally (but by default) capturing the
|
||||
stack trace as part of your error. This behavior can be turned off and on for
|
||||
specific error classes and comes in two flavors. You can have the stack trace
|
||||
be appended to the error's Error() message, or you can have the stack trace
|
||||
be logged immediately, every time an error of that type is instantiated.
|
||||
|
||||
Every error and error class supports hierarchical settings, in the sense that
|
||||
if a setting was not explicitly set on that error or error class, setting
|
||||
resolution traverses the error class hierarchy until it finds a valid setting,
|
||||
or returns the default.
|
||||
|
||||
See CaptureStack()/NoCaptureStack() and LogOnCreation()/NoLogOnCreation() for
|
||||
how to control this feature.
|
||||
|
||||
Arbitrary error values
|
||||
|
||||
These hierarchical settings (for whether or not errors captured or logged stack
|
||||
traces) were so useful, we generalized the system to allow users to extend
|
||||
the errors system with their own values. A user can tag a specific error with
|
||||
some value given a statically defined key, or tag a whole error class subtree.
|
||||
|
||||
Arbitrary error values can easily handle situtations like net.Error's
|
||||
Temporary() field, where some errors are temporary and others aren't. This can
|
||||
be mimicked as follows:
|
||||
|
||||
package netmimic
|
||||
|
||||
import (
|
||||
"github.com/spacemonkeygo/errors"
|
||||
)
|
||||
|
||||
var (
|
||||
NetError = errors.NewClass("Net Error")
|
||||
OpError = NetError.NewClass("Op Error")
|
||||
|
||||
tempErrorKey = errors.GenSym()
|
||||
)
|
||||
|
||||
func SetIsTemporary() errors.ErrorOption {
|
||||
return errors.SetData(tempErrorKey, true)
|
||||
}
|
||||
|
||||
func IsTemporary(err error) bool {
|
||||
v, ok := errors.GetData(err, tempErrorKey).(bool)
|
||||
if !ok {
|
||||
return false
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
func NetworkOp() error {
|
||||
// actually do something here
|
||||
return OpError.NewWith("failed operation", SetIsTemporary())
|
||||
}
|
||||
|
||||
func Example() error {
|
||||
for {
|
||||
err := NetworkOp()
|
||||
if err != nil {
|
||||
if IsTemporary(err) {
|
||||
// probably should do exponential backoff
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
HTTP handling
|
||||
|
||||
Another great example of arbitrary error value functionality is the errhttp
|
||||
subpackage. See the errhttp source for more examples of how to use
|
||||
SetData/GetData.
|
||||
|
||||
The errhttp package really helped clean up our error code. Take a look to
|
||||
see if it can help your error handling with HTTP stacks too.
|
||||
|
||||
http://godoc.org/github.com/spacemonkeygo/errors/errhttp
|
||||
|
||||
Exit recording
|
||||
|
||||
So you have stack traces, which tells you how the error was generated, but
|
||||
perhaps you're interested in keeping track of how the error was handled?
|
||||
|
||||
Every time you call errors.Record(err), it adds the current line information
|
||||
to the error's output. As an example:
|
||||
|
||||
func MyFunction() error {
|
||||
err := Something()
|
||||
if err != nil {
|
||||
if IsTemporary(err) {
|
||||
// manage the temporary error
|
||||
return errors.Record(err)
|
||||
} else {
|
||||
// manage the permanent error
|
||||
return errors.Record(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
errors.Record will help you keep track of which error handling branch your
|
||||
code took.
|
||||
|
||||
ErrorGroup
|
||||
|
||||
There's a few different types of ErrorGroup utilities in this package, but they
|
||||
all work the same way. Make sure to check out the ErrorGroup example.
|
||||
|
||||
CatchPanic
|
||||
|
||||
CatchPanic helps you easily manage functions that you think might panic, and
|
||||
instead return errors. CatchPanic works by taking a pointer to your named error
|
||||
return value. Check out the CatchPanic example for more.
|
||||
|
||||
Footnotes
|
||||
|
||||
[1] This errors package started while porting a large Python codebase to Go.
|
||||
https://www.spacemonkey.com/blog/posts/go-space-monkey
|
||||
*/
|
||||
package errors
|
648
vendor/github.com/spacemonkeygo/errors/errors.go
generated
vendored
648
vendor/github.com/spacemonkeygo/errors/errors.go
generated
vendored
|
@ -1,648 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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 errors
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
logOnCreation = GenSym()
|
||||
captureStack = GenSym()
|
||||
disableInheritance = GenSym()
|
||||
)
|
||||
|
||||
// ErrorClass is the basic hierarchical error type. An ErrorClass generates
|
||||
// actual errors, but the error class controls properties of the errors it
|
||||
// generates, such as where those errors are in the hierarchy, whether or not
|
||||
// they capture the stack on instantiation, and so forth.
|
||||
type ErrorClass struct {
|
||||
parent *ErrorClass
|
||||
name string
|
||||
data map[DataKey]interface{}
|
||||
}
|
||||
|
||||
var (
|
||||
// HierarchicalError is the base class for all hierarchical errors generated
|
||||
// through this class.
|
||||
HierarchicalError = &ErrorClass{
|
||||
parent: nil,
|
||||
name: "Error",
|
||||
data: map[DataKey]interface{}{captureStack: true}}
|
||||
|
||||
// SystemError is the base error class for errors not generated through this
|
||||
// errors library. It is not expected that anyone would ever generate new
|
||||
// errors from a SystemError type or make subclasses.
|
||||
SystemError = &ErrorClass{
|
||||
parent: nil,
|
||||
name: "System Error",
|
||||
data: map[DataKey]interface{}{}}
|
||||
)
|
||||
|
||||
// An ErrorOption is something that controls behavior of specific error
|
||||
// instances. They can be set on ErrorClasses or errors individually.
|
||||
type ErrorOption func(map[DataKey]interface{})
|
||||
|
||||
// SetData will take the given value and store it with the error or error class
|
||||
// and its descendents associated with the given DataKey. Be sure to check out
|
||||
// the example. value can be nil to disable values for subhierarchies.
|
||||
func SetData(key DataKey, value interface{}) ErrorOption {
|
||||
return func(m map[DataKey]interface{}) {
|
||||
m[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
// LogOnCreation tells the error class and its descendents to log the stack
|
||||
// whenever an error of this class is created.
|
||||
func LogOnCreation() ErrorOption {
|
||||
return SetData(logOnCreation, true)
|
||||
}
|
||||
|
||||
// CaptureStack tells the error class and its descendents to capture the stack
|
||||
// whenever an error of this class is created, and output it as part of the
|
||||
// error's Error() method. This is the default.
|
||||
func CaptureStack() ErrorOption {
|
||||
return SetData(captureStack, true)
|
||||
}
|
||||
|
||||
// NoLogOnCreation is the opposite of LogOnCreation and applies to the error,
|
||||
// class, and its descendents. This is the default.
|
||||
func NoLogOnCreation() ErrorOption {
|
||||
return SetData(logOnCreation, false)
|
||||
}
|
||||
|
||||
// NoCaptureStack is the opposite of CaptureStack and applies to the error,
|
||||
// class, and its descendents.
|
||||
func NoCaptureStack() ErrorOption {
|
||||
return SetData(captureStack, false)
|
||||
}
|
||||
|
||||
// If DisableInheritance is provided, the error or error class will belong to
|
||||
// its ancestors, but will not inherit their settings and options. Use with
|
||||
// caution, and may disappear in future releases.
|
||||
func DisableInheritance() ErrorOption {
|
||||
return SetData(disableInheritance, true)
|
||||
}
|
||||
|
||||
func boolWrapper(val interface{}, default_value bool) bool {
|
||||
rv, ok := val.(bool)
|
||||
if ok {
|
||||
return rv
|
||||
}
|
||||
return default_value
|
||||
}
|
||||
|
||||
// NewClass creates an error class with the provided name and options. Classes
|
||||
// generated from this method and not *ErrorClass.NewClass will descend from
|
||||
// the root HierarchicalError base class.
|
||||
func NewClass(name string, options ...ErrorOption) *ErrorClass {
|
||||
return HierarchicalError.NewClass(name, options...)
|
||||
}
|
||||
|
||||
// New is for compatibility with the default Go errors package. It simply
|
||||
// creates an error from the HierarchicalError root class.
|
||||
func New(text string) error {
|
||||
// NewWith doesn't take a format string, even though we have no options.
|
||||
return HierarchicalError.NewWith(text)
|
||||
}
|
||||
|
||||
// NewClass creates an error class with the provided name and options. The new
|
||||
// class will descend from the receiver.
|
||||
func (parent *ErrorClass) NewClass(name string,
|
||||
options ...ErrorOption) *ErrorClass {
|
||||
|
||||
ec := &ErrorClass{
|
||||
parent: parent,
|
||||
name: name,
|
||||
data: make(map[DataKey]interface{})}
|
||||
|
||||
for _, option := range options {
|
||||
option(ec.data)
|
||||
}
|
||||
|
||||
if !boolWrapper(ec.data[disableInheritance], false) {
|
||||
// hoist options for speed
|
||||
for key, val := range parent.data {
|
||||
_, exists := ec.data[key]
|
||||
if !exists {
|
||||
ec.data[key] = val
|
||||
}
|
||||
}
|
||||
return ec
|
||||
} else {
|
||||
delete(ec.data, disableInheritance)
|
||||
}
|
||||
|
||||
return ec
|
||||
}
|
||||
|
||||
// MustAddData allows adding data key value pairs to error classes after they
|
||||
// are created. This is useful for allowing external packages add namespaced
|
||||
// values to errors defined outside of their package. It will panic if the
|
||||
// key is already set in the error class.
|
||||
func (e *ErrorClass) MustAddData(key DataKey, value interface{}) {
|
||||
if _, ex := e.data[key]; ex {
|
||||
panic("key already exists")
|
||||
}
|
||||
e.data[key] = value
|
||||
}
|
||||
|
||||
// GetData will return any data set on the error class for the given key. It
|
||||
// returns nil if there is no data set for that key.
|
||||
func (e *ErrorClass) GetData(key DataKey) interface{} {
|
||||
return e.data[key]
|
||||
}
|
||||
|
||||
// Parent returns this error class' direct ancestor.
|
||||
func (e *ErrorClass) Parent() *ErrorClass {
|
||||
return e.parent
|
||||
}
|
||||
|
||||
// String returns this error class' name
|
||||
func (e *ErrorClass) String() string {
|
||||
if e == nil {
|
||||
return "nil"
|
||||
}
|
||||
return e.name
|
||||
}
|
||||
|
||||
// Is returns true if the receiver class is or is a descendent of parent.
|
||||
func (e *ErrorClass) Is(parent *ErrorClass) bool {
|
||||
for check := e; check != nil; check = check.parent {
|
||||
if check == parent {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// frame logs the pc at some point during execution.
|
||||
type frame struct {
|
||||
pc uintptr
|
||||
}
|
||||
|
||||
// String returns a human readable form of the frame.
|
||||
func (e frame) String() string {
|
||||
if e.pc == 0 {
|
||||
return "unknown.unknown:0"
|
||||
}
|
||||
f := runtime.FuncForPC(e.pc)
|
||||
if f == nil {
|
||||
return "unknown.unknown:0"
|
||||
}
|
||||
file, line := f.FileLine(e.pc)
|
||||
return fmt.Sprintf("%s:%s:%d", f.Name(), filepath.Base(file), line)
|
||||
}
|
||||
|
||||
// callerState records the pc into an frame for two callers up.
|
||||
func callerState(depth int) frame {
|
||||
pc, _, _, ok := runtime.Caller(depth)
|
||||
if !ok {
|
||||
return frame{pc: 0}
|
||||
}
|
||||
return frame{pc: pc}
|
||||
}
|
||||
|
||||
// record will record the pc at the given depth into the error if it is
|
||||
// capable of recording it.
|
||||
func record(err error, depth int) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
cast.exits = append(cast.exits, callerState(depth))
|
||||
return cast
|
||||
}
|
||||
|
||||
// Record will record the current pc on the given error if possible, adding
|
||||
// to the error's recorded exits list. Returns the given error argument.
|
||||
func Record(err error) error {
|
||||
return record(err, 3)
|
||||
}
|
||||
|
||||
// RecordBefore will record the pc depth frames above the current stack frame
|
||||
// on the given error if possible, adding to the error's recorded exits list.
|
||||
// Record(err) is equivalent to RecordBefore(err, 0). Returns the given error
|
||||
// argument.
|
||||
func RecordBefore(err error, depth int) error {
|
||||
return record(err, 3+depth)
|
||||
}
|
||||
|
||||
// Error is the type that represents a specific error instance. It is not
|
||||
// expected that you will work with *Error classes directly. Instead, you
|
||||
// should use the 'error' interface and errors package methods that operate
|
||||
// on errors instances.
|
||||
type Error struct {
|
||||
err error
|
||||
class *ErrorClass
|
||||
stacks [][]frame
|
||||
exits []frame
|
||||
data map[DataKey]interface{}
|
||||
}
|
||||
|
||||
// GetData returns the value associated with the given DataKey on this error
|
||||
// or any of its ancestors. Please see the example for SetData
|
||||
func (e *Error) GetData(key DataKey) interface{} {
|
||||
if e.data != nil {
|
||||
val, ok := e.data[key]
|
||||
if ok {
|
||||
return val
|
||||
}
|
||||
if boolWrapper(e.data[disableInheritance], false) {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return e.class.data[key]
|
||||
}
|
||||
|
||||
// GetData returns the value associated with the given DataKey on this error
|
||||
// or any of its ancestors. Please see the example for SetData
|
||||
func GetData(err error, key DataKey) interface{} {
|
||||
cast, ok := err.(*Error)
|
||||
if ok {
|
||||
return cast.GetData(key)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *ErrorClass) wrap(err error, classes []*ErrorClass,
|
||||
options []ErrorOption) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if ec, ok := err.(*Error); ok {
|
||||
if ec.Is(e) {
|
||||
if len(options) == 0 {
|
||||
return ec
|
||||
}
|
||||
// if we have options, we have to wrap it cause we don't want to
|
||||
// mutate the existing error.
|
||||
} else {
|
||||
for _, class := range classes {
|
||||
if ec.Is(class) {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rv := &Error{err: err, class: e}
|
||||
if len(options) > 0 {
|
||||
rv.data = make(map[DataKey]interface{})
|
||||
for _, option := range options {
|
||||
option(rv.data)
|
||||
}
|
||||
}
|
||||
|
||||
if boolWrapper(rv.GetData(captureStack), false) {
|
||||
rv.stacks = [][]frame{getStack(3)}
|
||||
}
|
||||
if boolWrapper(rv.GetData(logOnCreation), false) {
|
||||
LogWithStack(rv.Error())
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
func getStack(depth int) (stack []frame) {
|
||||
var pcs [256]uintptr
|
||||
amount := runtime.Callers(depth+1, pcs[:])
|
||||
stack = make([]frame, amount)
|
||||
for i := 0; i < amount; i++ {
|
||||
stack[i] = frame{pcs[i]}
|
||||
}
|
||||
return stack
|
||||
}
|
||||
|
||||
// AttachStack adds another stack to the current error's stack trace if it
|
||||
// exists
|
||||
func AttachStack(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
if len(cast.stacks) < 1 {
|
||||
// only record stacks if this error was supposed to
|
||||
return
|
||||
}
|
||||
cast.stacks = append(cast.stacks, getStack(2))
|
||||
}
|
||||
|
||||
// WrapUnless wraps the given error in the receiver error class unless the
|
||||
// error is already an instance of one of the provided error classes.
|
||||
func (e *ErrorClass) WrapUnless(err error, classes ...*ErrorClass) error {
|
||||
return e.wrap(err, classes, nil)
|
||||
}
|
||||
|
||||
// Wrap wraps the given error in the receiver error class with the provided
|
||||
// error-specific options.
|
||||
func (e *ErrorClass) Wrap(err error, options ...ErrorOption) error {
|
||||
return e.wrap(err, nil, options)
|
||||
}
|
||||
|
||||
// New makes a new error type. It takes a format string.
|
||||
func (e *ErrorClass) New(format string, args ...interface{}) error {
|
||||
return e.wrap(fmt.Errorf(format, args...), nil, nil)
|
||||
}
|
||||
|
||||
// NewWith makes a new error type with the provided error-specific options.
|
||||
func (e *ErrorClass) NewWith(message string, options ...ErrorOption) error {
|
||||
return e.wrap(errors.New(message), nil, options)
|
||||
}
|
||||
|
||||
// Error conforms to the error interface. Error will return the backtrace if
|
||||
// it was captured and any recorded exits.
|
||||
func (e *Error) Error() string {
|
||||
message := strings.TrimRight(e.err.Error(), "\n ")
|
||||
if strings.Contains(message, "\n") {
|
||||
message = fmt.Sprintf("%s:\n %s", e.class.String(),
|
||||
strings.Replace(message, "\n", "\n ", -1))
|
||||
} else {
|
||||
message = fmt.Sprintf("%s: %s", e.class.String(), message)
|
||||
}
|
||||
if stack := e.Stack(); stack != "" {
|
||||
message = fmt.Sprintf(
|
||||
"%s\n\"%s\" backtrace:\n%s", message, e.class, stack)
|
||||
}
|
||||
if exits := e.Exits(); exits != "" {
|
||||
message = fmt.Sprintf(
|
||||
"%s\n\"%s\" exits:\n%s", message, e.class, exits)
|
||||
}
|
||||
return message
|
||||
}
|
||||
|
||||
// Message returns just the error message without the backtrace or exits.
|
||||
func (e *Error) Message() string {
|
||||
message := strings.TrimRight(GetMessage(e.err), "\n ")
|
||||
if strings.Contains(message, "\n") {
|
||||
return fmt.Sprintf("%s:\n %s", e.class.String(),
|
||||
strings.Replace(message, "\n", "\n ", -1))
|
||||
}
|
||||
return fmt.Sprintf("%s: %s", e.class.String(), message)
|
||||
}
|
||||
|
||||
// WrappedErr returns the wrapped error, if the current error is simply
|
||||
// wrapping some previously returned error or system error. You probably want
|
||||
// the package-level WrappedErr
|
||||
func (e *Error) WrappedErr() error {
|
||||
return e.err
|
||||
}
|
||||
|
||||
// WrappedErr returns the wrapped error, if the current error is simply
|
||||
// wrapping some previously returned error or system error. If the error isn't
|
||||
// hierarchical it is just returned.
|
||||
func WrappedErr(err error) error {
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err
|
||||
}
|
||||
return cast.WrappedErr()
|
||||
}
|
||||
|
||||
// Class will return the appropriate error class for the given error. You
|
||||
// probably want the package-level GetClass.
|
||||
func (e *Error) Class() *ErrorClass {
|
||||
return e.class
|
||||
}
|
||||
|
||||
// Name returns the name of the error: in this case the name of the class the
|
||||
// error belongs to.
|
||||
func (e *Error) Name() (string, bool) {
|
||||
return e.class.name, true
|
||||
}
|
||||
|
||||
// GetClass will return the appropriate error class for the given error.
|
||||
// If the error is not nil, GetClass always returns a hierarchical error class,
|
||||
// and even attempts to determine a class for common system error types.
|
||||
func GetClass(err error) *ErrorClass {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return findSystemErrorClass(err)
|
||||
}
|
||||
return cast.class
|
||||
}
|
||||
|
||||
// Stack will return the stack associated with the error if one is found. You
|
||||
// probably want the package-level GetStack.
|
||||
func (e *Error) Stack() string {
|
||||
if len(e.stacks) > 0 {
|
||||
var frames []string
|
||||
for _, stack := range e.stacks {
|
||||
if frames == nil {
|
||||
frames = make([]string, 0, len(stack))
|
||||
} else {
|
||||
frames = append(frames, "----- attached stack -----")
|
||||
}
|
||||
for _, f := range stack {
|
||||
frames = append(frames, f.String())
|
||||
}
|
||||
}
|
||||
return strings.Join(frames, "\n")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetStack will return the stack associated with the error if one is found.
|
||||
func GetStack(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return cast.Stack()
|
||||
}
|
||||
|
||||
// Exits will return the exits recorded on the error if any are found. You
|
||||
// probably want the package-level GetExits.
|
||||
func (e *Error) Exits() string {
|
||||
if len(e.exits) > 0 {
|
||||
exits := make([]string, len(e.exits))
|
||||
for i, ex := range e.exits {
|
||||
exits[i] = ex.String()
|
||||
}
|
||||
return strings.Join(exits, "\n")
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// GetExits will return the exits recorded on the error if any are found.
|
||||
func GetExits(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
return cast.Exits()
|
||||
}
|
||||
|
||||
// GetMessage returns just the error message without the backtrace or exits.
|
||||
func GetMessage(err error) string {
|
||||
if err == nil {
|
||||
return ""
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return err.Error()
|
||||
}
|
||||
return cast.Message()
|
||||
}
|
||||
|
||||
// EquivalenceOption values control behavior of determining whether or not an
|
||||
// error belongs to a specific class.
|
||||
type EquivalenceOption int
|
||||
|
||||
const (
|
||||
// If IncludeWrapped is used, wrapped errors are also used for determining
|
||||
// class membership.
|
||||
IncludeWrapped EquivalenceOption = 1
|
||||
)
|
||||
|
||||
func combineEquivOpts(opts []EquivalenceOption) (rv EquivalenceOption) {
|
||||
for _, opt := range opts {
|
||||
rv |= opt
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
// Is returns whether or not an error belongs to a specific class. Typically
|
||||
// you should use Contains instead.
|
||||
func (e *Error) Is(ec *ErrorClass, opts ...EquivalenceOption) bool {
|
||||
return ec.Contains(e, opts...)
|
||||
}
|
||||
|
||||
// Contains returns whether or not the receiver error class contains the given
|
||||
// error instance.
|
||||
func (e *ErrorClass) Contains(err error, opts ...EquivalenceOption) bool {
|
||||
if err == nil {
|
||||
return false
|
||||
}
|
||||
cast, ok := err.(*Error)
|
||||
if !ok {
|
||||
return findSystemErrorClass(err).Is(e)
|
||||
}
|
||||
if cast.class.Is(e) {
|
||||
return true
|
||||
}
|
||||
if combineEquivOpts(opts)&IncludeWrapped == 0 {
|
||||
return false
|
||||
}
|
||||
return e.Contains(cast.err, opts...)
|
||||
}
|
||||
|
||||
var (
|
||||
// Useful error classes
|
||||
NotImplementedError = NewClass("Not Implemented Error", LogOnCreation())
|
||||
ProgrammerError = NewClass("Programmer Error", LogOnCreation())
|
||||
PanicError = NewClass("Panic Error", LogOnCreation())
|
||||
|
||||
// The following SystemError descendants are provided such that the GetClass
|
||||
// method has something to return for standard library error types not
|
||||
// defined through this class.
|
||||
//
|
||||
// It is not expected that anyone would create instances of these classes.
|
||||
//
|
||||
// from os
|
||||
SyscallError = SystemError.NewClass("Syscall Error")
|
||||
// from syscall
|
||||
ErrnoError = SystemError.NewClass("Errno Error")
|
||||
// from net
|
||||
NetworkError = SystemError.NewClass("Network Error")
|
||||
UnknownNetworkError = NetworkError.NewClass("Unknown Network Error")
|
||||
AddrError = NetworkError.NewClass("Addr Error")
|
||||
InvalidAddrError = AddrError.NewClass("Invalid Addr Error")
|
||||
NetOpError = NetworkError.NewClass("Network Op Error")
|
||||
NetParseError = NetworkError.NewClass("Network Parse Error")
|
||||
DNSError = NetworkError.NewClass("DNS Error")
|
||||
DNSConfigError = DNSError.NewClass("DNS Config Error")
|
||||
// from io
|
||||
IOError = SystemError.NewClass("IO Error")
|
||||
EOF = IOError.NewClass("EOF")
|
||||
ClosedPipeError = IOError.NewClass("Closed Pipe Error")
|
||||
NoProgressError = IOError.NewClass("No Progress Error")
|
||||
ShortBufferError = IOError.NewClass("Short Buffer Error")
|
||||
ShortWriteError = IOError.NewClass("Short Write Error")
|
||||
UnexpectedEOFError = IOError.NewClass("Unexpected EOF Error")
|
||||
// from context
|
||||
ContextError = SystemError.NewClass("Context Error")
|
||||
ContextCanceled = ContextError.NewClass("Canceled")
|
||||
ContextTimeout = ContextError.NewClass("Timeout")
|
||||
)
|
||||
|
||||
func findSystemErrorClass(err error) *ErrorClass {
|
||||
switch err {
|
||||
case io.EOF:
|
||||
return EOF
|
||||
case io.ErrUnexpectedEOF:
|
||||
return UnexpectedEOFError
|
||||
case io.ErrClosedPipe:
|
||||
return ClosedPipeError
|
||||
case io.ErrNoProgress:
|
||||
return NoProgressError
|
||||
case io.ErrShortBuffer:
|
||||
return ShortBufferError
|
||||
case io.ErrShortWrite:
|
||||
return ShortWriteError
|
||||
case contextCanceled:
|
||||
return ContextCanceled
|
||||
case contextDeadlineExceeded:
|
||||
return ContextTimeout
|
||||
default:
|
||||
break
|
||||
}
|
||||
if isErrnoError(err) {
|
||||
return ErrnoError
|
||||
}
|
||||
switch err.(type) {
|
||||
case *os.SyscallError:
|
||||
return SyscallError
|
||||
case net.UnknownNetworkError:
|
||||
return UnknownNetworkError
|
||||
case *net.AddrError:
|
||||
return AddrError
|
||||
case net.InvalidAddrError:
|
||||
return InvalidAddrError
|
||||
case *net.OpError:
|
||||
return NetOpError
|
||||
case *net.ParseError:
|
||||
return NetParseError
|
||||
case *net.DNSError:
|
||||
return DNSError
|
||||
case *net.DNSConfigError:
|
||||
return DNSConfigError
|
||||
case net.Error:
|
||||
return NetworkError
|
||||
default:
|
||||
return SystemError
|
||||
}
|
||||
}
|
26
vendor/github.com/spacemonkeygo/errors/syscall.go
generated
vendored
26
vendor/github.com/spacemonkeygo/errors/syscall.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build !appengine
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func isErrnoError(err error) bool {
|
||||
_, ok := err.(syscall.Errno)
|
||||
return ok
|
||||
}
|
21
vendor/github.com/spacemonkeygo/errors/syscall_ae.go
generated
vendored
21
vendor/github.com/spacemonkeygo/errors/syscall_ae.go
generated
vendored
|
@ -1,21 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build appengine
|
||||
|
||||
package errors
|
||||
|
||||
func isErrnoError(err error) bool {
|
||||
return false
|
||||
}
|
155
vendor/github.com/spacemonkeygo/errors/utils.go
generated
vendored
155
vendor/github.com/spacemonkeygo/errors/utils.go
generated
vendored
|
@ -1,155 +0,0 @@
|
|||
// Copyright (C) 2014 Space Monkey, Inc.
|
||||
//
|
||||
// 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 errors
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// Change this method if you want errors to log somehow else
|
||||
LogMethod = log.Printf
|
||||
|
||||
ErrorGroupError = NewClass("Error Group Error")
|
||||
)
|
||||
|
||||
// LogWithStack will log the given messages with the current stack
|
||||
func LogWithStack(messages ...interface{}) {
|
||||
buf := make([]byte, Config.Stacklogsize)
|
||||
buf = buf[:runtime.Stack(buf, false)]
|
||||
LogMethod("%s\n%s", fmt.Sprintln(messages...), buf)
|
||||
}
|
||||
|
||||
// CatchPanic can be used to catch panics and turn them into errors. See the
|
||||
// example.
|
||||
func CatchPanic(err_ref *error) {
|
||||
r := recover()
|
||||
if r == nil {
|
||||
return
|
||||
}
|
||||
err, ok := r.(error)
|
||||
if ok {
|
||||
*err_ref = PanicError.Wrap(err)
|
||||
return
|
||||
}
|
||||
*err_ref = PanicError.New("%v", r)
|
||||
}
|
||||
|
||||
// ErrorGroup is a type for collecting errors from a bunch of independent
|
||||
// tasks. ErrorGroups are not threadsafe. See the example for usage.
|
||||
type ErrorGroup struct {
|
||||
Errors []error
|
||||
limit int
|
||||
excess int
|
||||
}
|
||||
|
||||
// NewErrorGroup makes a new ErrorGroup
|
||||
func NewErrorGroup() *ErrorGroup { return &ErrorGroup{} }
|
||||
|
||||
// NewBoundedErrorGroup makes a new ErrorGroup that will not track more than
|
||||
// limit errors. Once the limit is reached, the ErrorGroup will track
|
||||
// additional errors as excess.
|
||||
func NewBoundedErrorGroup(limit int) *ErrorGroup {
|
||||
return &ErrorGroup{
|
||||
limit: limit,
|
||||
}
|
||||
}
|
||||
|
||||
// Add is called with errors. nil errors are ignored.
|
||||
func (e *ErrorGroup) Add(err error) {
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if e.limit > 0 && len(e.Errors) == e.limit {
|
||||
e.excess++
|
||||
} else {
|
||||
e.Errors = append(e.Errors, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize will collate all the found errors. If no errors were found, it will
|
||||
// return nil. If one error was found, it will be returned directly. Otherwise
|
||||
// an ErrorGroupError will be returned.
|
||||
func (e *ErrorGroup) Finalize() error {
|
||||
if len(e.Errors) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(e.Errors) == 1 && e.excess == 0 {
|
||||
return e.Errors[0]
|
||||
}
|
||||
msgs := make([]string, 0, len(e.Errors))
|
||||
for _, err := range e.Errors {
|
||||
msgs = append(msgs, err.Error())
|
||||
}
|
||||
if e.excess > 0 {
|
||||
msgs = append(msgs, fmt.Sprintf("... and %d more.", e.excess))
|
||||
e.excess = 0
|
||||
}
|
||||
e.Errors = nil
|
||||
return ErrorGroupError.New(strings.Join(msgs, "\n"))
|
||||
}
|
||||
|
||||
// LoggingErrorGroup is similar to ErrorGroup except that instead of collecting
|
||||
// all of the errors, it logs the errors immediately and just counts how many
|
||||
// non-nil errors have been seen. See the ErrorGroup example for usage.
|
||||
type LoggingErrorGroup struct {
|
||||
name string
|
||||
total int
|
||||
failed int
|
||||
}
|
||||
|
||||
// NewLoggingErrorGroup returns a new LoggingErrorGroup with the given name.
|
||||
func NewLoggingErrorGroup(name string) *LoggingErrorGroup {
|
||||
return &LoggingErrorGroup{name: name}
|
||||
}
|
||||
|
||||
// Add will handle a given error. If the error is non-nil, total and failed
|
||||
// are both incremented and the error is logged. If the error is nil, only
|
||||
// total is incremented.
|
||||
func (e *LoggingErrorGroup) Add(err error) {
|
||||
e.total++
|
||||
if err != nil {
|
||||
LogMethod("%s: %s", e.name, err)
|
||||
e.failed++
|
||||
}
|
||||
}
|
||||
|
||||
// Finalize returns no error if no failures were observed, otherwise it will
|
||||
// return an ErrorGroupError with statistics about the observed errors.
|
||||
func (e *LoggingErrorGroup) Finalize() (err error) {
|
||||
if e.failed > 0 {
|
||||
err = ErrorGroupError.New("%s: %d of %d failed.", e.name, e.failed,
|
||||
e.total)
|
||||
}
|
||||
e.total = 0
|
||||
e.failed = 0
|
||||
return err
|
||||
}
|
||||
|
||||
type Finalizer interface {
|
||||
Finalize() error
|
||||
}
|
||||
|
||||
// Finalize takes a group of ErrorGroups and joins them together into one error
|
||||
func Finalize(finalizers ...Finalizer) error {
|
||||
var errs ErrorGroup
|
||||
for _, finalizer := range finalizers {
|
||||
errs.Add(finalizer.Finalize())
|
||||
}
|
||||
return errs.Finalize()
|
||||
}
|
26
vendor/github.com/spacemonkeygo/errors/xctx.go
generated
vendored
26
vendor/github.com/spacemonkeygo/errors/xctx.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// Copyright (C) 2016 Space Monkey, Inc.
|
||||
//
|
||||
// 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.
|
||||
|
||||
// +build !go1.7
|
||||
|
||||
package errors
|
||||
|
||||
import (
|
||||
"golang.org/x/net/context"
|
||||
)
|
||||
|
||||
var (
|
||||
contextCanceled = context.Canceled
|
||||
contextDeadlineExceeded = context.DeadlineExceeded
|
||||
)
|
9
vendor/github.com/vivint/infectious/berlekamp_welch.go
generated
vendored
9
vendor/github.com/vivint/infectious/berlekamp_welch.go
generated
vendored
|
@ -23,6 +23,7 @@
|
|||
package infectious
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sort"
|
||||
)
|
||||
|
||||
|
@ -50,7 +51,7 @@ func (f *FEC) Decode(dst []byte, shares []Share) ([]byte, error) {
|
|||
}
|
||||
|
||||
if len(shares) == 0 {
|
||||
return nil, Error.New("must specify at least one share")
|
||||
return nil, errors.New("must specify at least one share")
|
||||
}
|
||||
piece_len := len(shares[0].Data)
|
||||
result_len := piece_len * f.k
|
||||
|
@ -78,7 +79,7 @@ func (f *FEC) decode(shares []Share, output func(Share)) error {
|
|||
// mutating the underlying byte slices and reordering the shares
|
||||
func (fc *FEC) Correct(shares []Share) error {
|
||||
if len(shares) < fc.k {
|
||||
return Error.New("must specify at least the number of required shares")
|
||||
return errors.New("must specify at least the number of required shares")
|
||||
}
|
||||
|
||||
sort.Sort(byNumber(shares))
|
||||
|
@ -124,7 +125,7 @@ func (fc *FEC) berlekampWelch(shares []Share, index int) ([]byte, error) {
|
|||
q := e + k // def of Q polynomial
|
||||
|
||||
if e <= 0 {
|
||||
return nil, NotEnoughShares.New("")
|
||||
return nil, NotEnoughShares
|
||||
}
|
||||
|
||||
const interp_base = gfVal(2)
|
||||
|
@ -194,7 +195,7 @@ func (fc *FEC) berlekampWelch(shares []Share, index int) ([]byte, error) {
|
|||
}
|
||||
|
||||
if !rem.isZero() {
|
||||
return nil, TooManyErrors.New("")
|
||||
return nil, TooManyErrors
|
||||
}
|
||||
|
||||
out := make([]byte, fc.n)
|
||||
|
|
12
vendor/github.com/vivint/infectious/common.go
generated
vendored
12
vendor/github.com/vivint/infectious/common.go
generated
vendored
|
@ -36,13 +36,15 @@
|
|||
package infectious
|
||||
|
||||
import (
|
||||
"github.com/spacemonkeygo/errors"
|
||||
"errors"
|
||||
|
||||
"golang.org/x/sys/cpu"
|
||||
)
|
||||
|
||||
var Error = errors.NewClass("infectious")
|
||||
var NotEnoughShares = Error.NewClass("not enough shares")
|
||||
var TooManyErrors = Error.NewClass("too many errors")
|
||||
|
||||
var hasAVX2 = cpu.X86.HasAVX2
|
||||
var hasSSSE3 = cpu.X86.HasSSSE3
|
||||
|
||||
var (
|
||||
NotEnoughShares = errors.New("not enough shares")
|
||||
TooManyErrors = errors.New("too many errors to reconstruct")
|
||||
)
|
||||
|
|
22
vendor/github.com/vivint/infectious/fec.go
generated
vendored
22
vendor/github.com/vivint/infectious/fec.go
generated
vendored
|
@ -33,7 +33,11 @@
|
|||
|
||||
package infectious
|
||||
|
||||
import "sort"
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
// FEC represents operations performed on a Reed-Solomon-based
|
||||
// forward error correction code. Make sure to construct using NewFEC.
|
||||
|
@ -50,7 +54,7 @@ type FEC struct {
|
|||
// exist, corrupted data can be detected and recovered from.
|
||||
func NewFEC(k, n int) (*FEC, error) {
|
||||
if k <= 0 || n <= 0 || k > 256 || n > 256 || k > n {
|
||||
return nil, Error.New("requires 1 <= k <= n <= 256")
|
||||
return nil, errors.New("requires 1 <= k <= n <= 256")
|
||||
}
|
||||
|
||||
enc_matrix := make([]byte, n*k)
|
||||
|
@ -127,7 +131,7 @@ func (f *FEC) Encode(input []byte, output func(Share)) error {
|
|||
enc_matrix := f.enc_matrix
|
||||
|
||||
if size%k != 0 {
|
||||
return Error.New("input length must be a multiple of %d", k)
|
||||
return fmt.Errorf("input length must be a multiple of %d", k)
|
||||
}
|
||||
|
||||
block_size := size / k
|
||||
|
@ -173,21 +177,21 @@ func (f *FEC) EncodeSingle(input, output []byte, num int) error {
|
|||
enc_matrix := f.enc_matrix
|
||||
|
||||
if num < 0 {
|
||||
return Error.New("num must be non-negative")
|
||||
return errors.New("num must be non-negative")
|
||||
}
|
||||
|
||||
if num >= n {
|
||||
return Error.New("num must be less than %d", n)
|
||||
return fmt.Errorf("num must be less than %d", n)
|
||||
}
|
||||
|
||||
if size%k != 0 {
|
||||
return Error.New("input length must be a multiple of %d", k)
|
||||
return fmt.Errorf("input length must be a multiple of %d", k)
|
||||
}
|
||||
|
||||
block_size := size / k
|
||||
|
||||
if len(output) != block_size {
|
||||
return Error.New("output length must be %d", block_size)
|
||||
return fmt.Errorf("output length must be %d", block_size)
|
||||
}
|
||||
|
||||
if num < k {
|
||||
|
@ -246,7 +250,7 @@ func (f *FEC) Rebuild(shares []Share, output func(Share)) error {
|
|||
enc_matrix := f.enc_matrix
|
||||
|
||||
if len(shares) < k {
|
||||
return NotEnoughShares.New("")
|
||||
return NotEnoughShares
|
||||
}
|
||||
|
||||
share_size := len(shares[0].Data)
|
||||
|
@ -275,7 +279,7 @@ func (f *FEC) Rebuild(shares []Share, output func(Share)) error {
|
|||
}
|
||||
|
||||
if share_id >= n {
|
||||
return Error.New("invalid share id: %d", share_id)
|
||||
return fmt.Errorf("invalid share id: %d", share_id)
|
||||
}
|
||||
|
||||
if share_id < k {
|
||||
|
|
9
vendor/github.com/vivint/infectious/gf_alg.go
generated
vendored
9
vendor/github.com/vivint/infectious/gf_alg.go
generated
vendored
|
@ -23,6 +23,7 @@
|
|||
package infectious
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
@ -53,7 +54,7 @@ func (a gfVal) mul(b gfVal) gfVal {
|
|||
|
||||
func (a gfVal) div(b gfVal) (gfVal, error) {
|
||||
if b == 0 {
|
||||
return 0, Error.New("divide by zero")
|
||||
return 0, errors.New("divide by zero")
|
||||
}
|
||||
if a == 0 {
|
||||
return 0, nil
|
||||
|
@ -71,7 +72,7 @@ func (a gfVal) isZero() bool {
|
|||
|
||||
func (a gfVal) inv() (gfVal, error) {
|
||||
if a == 0 {
|
||||
return 0, Error.New("invert zero")
|
||||
return 0, errors.New("invert zero")
|
||||
}
|
||||
return gfVal(gf_exp[255-gf_log[a]]), nil
|
||||
}
|
||||
|
@ -173,7 +174,7 @@ func (p gfPoly) div(b gfPoly) (q, r gfPoly, err error) {
|
|||
b = b[1:]
|
||||
}
|
||||
if len(b) == 0 {
|
||||
return nil, nil, Error.New("divide by zero")
|
||||
return nil, nil, errors.New("divide by zero")
|
||||
}
|
||||
|
||||
// sanitize the base poly as well
|
||||
|
@ -221,7 +222,7 @@ func (p gfPoly) div(b gfPoly) (q, r gfPoly, err error) {
|
|||
|
||||
p = p.add(padded)
|
||||
if !p[0].isZero() {
|
||||
return nil, nil, Error.New("alg error: %x", p)
|
||||
return nil, nil, fmt.Errorf("alg error: %x", p)
|
||||
}
|
||||
p = p[1:]
|
||||
}
|
||||
|
|
5
vendor/github.com/vivint/infectious/go.mod
generated
vendored
Normal file
5
vendor/github.com/vivint/infectious/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
module github.com/vivint/infectious
|
||||
|
||||
go 1.12
|
||||
|
||||
require golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd
|
2
vendor/github.com/vivint/infectious/go.sum
generated
vendored
Normal file
2
vendor/github.com/vivint/infectious/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884=
|
||||
golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
9
vendor/github.com/vivint/infectious/math.go
generated
vendored
9
vendor/github.com/vivint/infectious/math.go
generated
vendored
|
@ -33,7 +33,10 @@
|
|||
|
||||
package infectious
|
||||
|
||||
import "bytes"
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
)
|
||||
|
||||
type pivotSearcher struct {
|
||||
k int
|
||||
|
@ -66,7 +69,7 @@ func (p *pivotSearcher) search(col int, matrix []byte) (int, int, error) {
|
|||
}
|
||||
}
|
||||
|
||||
return 0, 0, Error.New("pivot not found")
|
||||
return 0, 0, errors.New("pivot not found")
|
||||
}
|
||||
|
||||
func swap(a, b *byte) {
|
||||
|
@ -100,7 +103,7 @@ func invertMatrix(matrix []byte, k int) error {
|
|||
c := pivot_row[icol]
|
||||
|
||||
if c == 0 {
|
||||
return Error.New("singular matrix")
|
||||
return errors.New("singular matrix")
|
||||
}
|
||||
|
||||
if c != 1 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue