-
Notifications
You must be signed in to change notification settings - Fork 1
/
errors.go
115 lines (100 loc) · 3.54 KB
/
errors.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
package errors
import (
"fmt"
"strings"
)
// Op denotes an operation type.
//
// Indicates the operation performed when the error occurred.
type Op string
// Kind describes the kind of an error
type Kind uint8
// Defined error kinds.
const (
Inherit Kind = iota // Inherit kind when wrapping
Input // General input error
InputValue // Input has wrong "value" (e.g. not a monomial)
InputIncompatible // Inputs incompatible with each other
InputTooLarge // Input exceeds some upper bound
ArithmeticIncompat // Objects not compatible for given operation
Parsing // General parsing error
Conversion // Conversion error
Overflow // Overflow error
Internal // Internal error
)
// Error is the basic error object.
type Error struct {
Op Op // The operation causing the error
Kind Kind // The kind of error
Err error // The underlying error
}
// New creates a new error.
//
// The message can contain formatting directives for the inputs in formatArgs.
func New(op Op, kind Kind, message string, formatArgs ...interface{}) *Error {
return &Error{
Op: op,
Kind: kind,
Err: fmt.Errorf(message, formatArgs...),
}
}
// Wrap takes an existing error and wraps it in a new operation and kind.
func Wrap(op Op, kind Kind, err error) *Error {
return &Error{
Op: op,
Kind: kind,
Err: err,
}
}
// Is determines if an error has a certain kind.
//
// If err is not the Error type defined in this package, the function returns
// false.
func Is(kind Kind, err error) bool {
e, ok := err.(*Error)
switch {
case !ok:
return false
case e.Kind != Inherit:
return e.Kind == kind
}
return Is(kind, e.Err)
}
// Error formats the error as a string.
func (e *Error) Error() string {
var sb strings.Builder
if e.Op != "" {
fmt.Fprintf(&sb, "%s: ", e.Op)
}
if e.Err != nil {
fmt.Fprint(&sb, e.Err.Error())
}
return sb.String()
}
/* Copyright 2019 René Bødker Christensen
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. Neither the name of the copyright holder nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/