-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy patherrors.go
More file actions
84 lines (70 loc) · 2.38 KB
/
errors.go
File metadata and controls
84 lines (70 loc) · 2.38 KB
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
package gorums
import (
"errors"
"fmt"
"strings"
"github.com/relab/gorums/internal/stream"
)
// ErrIncomplete is the error returned by a quorum call when the call cannot be completed
// due to insufficient non-error replies to form a quorum according to the quorum function.
var ErrIncomplete = errors.New("incomplete call")
// ErrSendFailure is the error returned by a multicast call when message sending fails for one or more nodes.
var ErrSendFailure = errors.New("send failure")
// ErrTypeMismatch is returned when a response cannot be cast to the expected type.
var ErrTypeMismatch = stream.ErrTypeMismatch
// ErrSkipNode is returned when a node is skipped by request transformations.
// This allows the response iterator to account for all nodes without blocking.
var ErrSkipNode = errors.New("skip node")
// QuorumCallError reports on a failed quorum call.
// It provides detailed information about which nodes failed.
type QuorumCallError struct {
cause error
errors []nodeError
}
// Cause returns the underlying cause of the quorum call failure.
// Common causes include ErrIncomplete and ErrSendFailure.
func (e QuorumCallError) Cause() error {
return e.cause
}
// NodeErrors returns the number of nodes that failed during the quorum call.
func (e QuorumCallError) NodeErrors() int {
return len(e.errors)
}
// Is reports whether the target error is the same as the cause of the QuorumCallError.
func (e QuorumCallError) Is(target error) bool {
if t, ok := target.(QuorumCallError); ok {
return e.cause == t.cause
}
return e.cause == target
}
// Unwrap returns all the underlying node errors as a slice.
// This allows the error to work with errors.Is and errors.As for any wrapped errors.
func (e QuorumCallError) Unwrap() (errs []error) {
for _, ne := range e.errors {
errs = append(errs, ne.cause)
}
return errs
}
func (e QuorumCallError) Error() string {
s := fmt.Sprintf("quorum call error: %s (errors: %d)", e.cause, len(e.errors))
var b strings.Builder
b.WriteString(s)
if len(e.errors) == 0 {
return b.String()
}
b.WriteString("\nnode errors:\n")
for _, err := range e.errors {
b.WriteByte('\t')
b.WriteString(err.Error())
b.WriteByte('\n')
}
return b.String()
}
// nodeError reports on a failed RPC call from a specific node.
type nodeError struct {
cause error
nodeID uint32
}
func (e nodeError) Error() string {
return fmt.Sprintf("node %d: %v", e.nodeID, e.cause)
}