generated from xmidt-org/.go-template
-
Notifications
You must be signed in to change notification settings - Fork 1
/
exitCoder.go
77 lines (63 loc) · 2.17 KB
/
exitCoder.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
// SPDX-FileCopyrightText: 2023 Comcast Cable Communications Management, LLC
// SPDX-License-Identifier: Apache-2.0
package arrange
import "errors"
// DefaultErrorExitCode is used when no exit code could otherwise be
// determined for a non-nil error.
const DefaultErrorExitCode int = 1
// ExitCoder is an optional interface that an error can implement to supply
// an associated exit code with that error. Useful particularly with fx.ExitCode
// or to determine the process exit code upon an error.
type ExitCoder interface {
// ExitCode returns the exit code associated with this error.
ExitCode() int
}
type exitCodeErr struct {
error
exitCode int
}
func (ece exitCodeErr) ExitCode() int {
return ece.exitCode
}
func (ece exitCodeErr) Unwrap() error {
return ece.error
}
// UseExitCode returns a new error object that associates an existing error
// with an exit code. The new error will implement ExitCoder and will have
// an Unwrap method as described in the errors package.
//
// If err is nil, this function immediately panics so as not to delay a panic
// until the returned error is used.
func UseExitCode(err error, exitCode int) error {
if err == nil {
panic("cannot associate a nil error with an exit code")
}
return exitCodeErr{
error: err,
exitCode: exitCode,
}
}
// ErrorCoder is a strategy type for determining the exit code for an error.
// Note that this strategy will be invoked with a nil error to allow custom
// logic for returning exit codes indicating success.
type ErrorCoder func(error) int
// ExitCodeFor provides a standard way of determining the exit code associated
// with an error. Logic is applied in the following order:
//
// - If err implements ExitCoder, that exit code is returned
// - If coder is not nil, it is invoked to determine the exit code
// - If err is not nil, DefaultErrorExitCode is returned
// - If none of the above are true, this function returns zero (0).
func ExitCodeFor(err error, coder ErrorCoder) int {
var ec ExitCoder
switch {
case errors.As(err, &ec):
return ec.ExitCode()
case coder != nil:
return coder(err) // err can be nil
case err != nil:
return DefaultErrorExitCode
default:
return 0
}
}