-
Notifications
You must be signed in to change notification settings - Fork 176
/
errors.go
98 lines (80 loc) · 2.8 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
package engine
import (
"errors"
"fmt"
"github.com/rs/zerolog"
)
// InvalidInputError are errors for caused by invalid inputs.
// It's useful to distinguish these known errors from exceptions.
// By distinguishing errors from exceptions, we can log them
// differently.
// For instance, log InvalidInputError error as a warn log, and log
// other error as an error log.
type InvalidInputError struct {
err error
}
func NewInvalidInputError(msg string) error {
return NewInvalidInputErrorf(msg)
}
func NewInvalidInputErrorf(msg string, args ...interface{}) error {
return InvalidInputError{
err: fmt.Errorf(msg, args...),
}
}
func (e InvalidInputError) Unwrap() error {
return e.err
}
func (e InvalidInputError) Error() string {
return e.err.Error()
}
// IsInvalidInputError returns whether the given error is an InvalidInputError error
func IsInvalidInputError(err error) bool {
var errInvalidInputError InvalidInputError
return errors.As(err, &errInvalidInputError)
}
// OutdatedInputError are for inputs that are outdated. An outdated input doesn't mean
// whether the input was invalid or not, knowing that would take more computation that
// isn't necessary.
// An outdated input could also for a duplicated input: the duplication is outdated.
type OutdatedInputError struct {
err error
}
func NewOutdatedInputErrorf(msg string, args ...interface{}) error {
return OutdatedInputError{
err: fmt.Errorf(msg, args...),
}
}
func (e OutdatedInputError) Unwrap() error {
return e.err
}
func (e OutdatedInputError) Error() string {
return e.err.Error()
}
func IsOutdatedInputError(err error) bool {
var errOutdatedInputError OutdatedInputError
return errors.As(err, &errOutdatedInputError)
}
// LogError logs the engine processing error
func LogError(log zerolog.Logger, err error) {
msg := "could not process message"
// Invalid input errors could be logged as warning, because they can be
// part of normal operations when the network is open and anyone can send
// weird messages around. However, during the non-BFT phase where we
// control the majority of the network, we should not be seeing any of
// them. Logging them as error will help us to identify and address
// issues with our application logic before going full BFT.
if IsInvalidInputError(err) {
log.Error().Str("error_type", "invalid_input").Err(err).Msg(msg)
return
}
// Outdated input errors, on the other hand, can happen regularly, even
// before opening the network up, as some messages might just be late
// due to network delays or other infrastructure issues. They should
// thus be logged as warnings.
if IsOutdatedInputError(err) {
log.Warn().Str("error_type", "outdated_input").Err(err).Msg(msg)
return
}
// all other errors should just be logged as usual
log.Error().Str("error_type", "generic_error").Err(err).Msg(msg)
}