1package exec
2
3import "github.com/pkg/errors"
4
5var (
6	// ErrRuntimeUnsupported encountered when a task requires a runtime
7	// unsupported by the executor.
8	ErrRuntimeUnsupported = errors.New("exec: unsupported runtime")
9
10	// ErrTaskPrepared is called if the task is already prepared.
11	ErrTaskPrepared = errors.New("exec: task already prepared")
12
13	// ErrTaskStarted can be returned from any operation that cannot be
14	// performed because the task has already been started. This does not imply
15	// that the task is running but rather that it is no longer valid to call
16	// Start.
17	ErrTaskStarted = errors.New("exec: task already started")
18
19	// ErrTaskUpdateRejected is returned if a task update is rejected by a controller.
20	ErrTaskUpdateRejected = errors.New("exec: task update rejected")
21
22	// ErrControllerClosed returned when a task controller has been closed.
23	ErrControllerClosed = errors.New("exec: controller closed")
24
25	// ErrTaskRetry is returned by Do when an operation failed by should be
26	// retried. The status should still be reported in this case.
27	ErrTaskRetry = errors.New("exec: task retry")
28
29	// ErrTaskNoop returns when the a subsequent call to Do will not result in
30	// advancing the task. Callers should avoid calling Do until the task has been updated.
31	ErrTaskNoop = errors.New("exec: task noop")
32)
33
34// ExitCoder is implemented by errors that have an exit code.
35type ExitCoder interface {
36	// ExitCode returns the exit code.
37	ExitCode() int
38}
39
40// Temporary indicates whether or not the error condition is temporary.
41//
42// If this is encountered in the controller, the failing operation will be
43// retried when this returns true. Otherwise, the operation is considered
44// fatal.
45type Temporary interface {
46	Temporary() bool
47}
48
49// MakeTemporary makes the error temporary.
50func MakeTemporary(err error) error {
51	if IsTemporary(err) {
52		return err
53	}
54
55	return temporary{err}
56}
57
58type temporary struct {
59	error
60}
61
62func (t temporary) Cause() error    { return t.error }
63func (t temporary) Temporary() bool { return true }
64
65// IsTemporary returns true if the error or a recursive cause returns true for
66// temporary.
67func IsTemporary(err error) bool {
68	for err != nil {
69		if tmp, ok := err.(Temporary); ok && tmp.Temporary() {
70			return true
71		}
72
73		cause := errors.Cause(err)
74		if cause == err {
75			break
76		}
77
78		err = cause
79	}
80
81	return false
82}
83