@@ -55,7 +55,8 @@ type WaitForStateOption interface {
55
55
// fsmOptions is a struct that holds all options that can be passed to the
56
56
// WaitForState function.
57
57
type fsmOptions struct {
58
- initialWait time.Duration
58
+ initialWait time.Duration
59
+ abortEarlyOnError bool
59
60
}
60
61
61
62
// InitialWaitOption is an option that can be passed to the WaitForState
@@ -76,6 +77,24 @@ func (w *InitialWaitOption) apply(o *fsmOptions) {
76
77
o .initialWait = w .initialWait
77
78
}
78
79
80
+ // AbortEarlyOnErrorOption is an option that can be passed to the WaitForState
81
+ // function to abort early if an error occurs.
82
+ type AbortEarlyOnErrorOption struct {
83
+ abortEarlyOnError bool
84
+ }
85
+
86
+ // apply implements the WaitForStateOption interface.
87
+ func (a * AbortEarlyOnErrorOption ) apply (o * fsmOptions ) {
88
+ o .abortEarlyOnError = a .abortEarlyOnError
89
+ }
90
+
91
+ // WithAbortEarlyOnErrorOption creates a new AbortEarlyOnErrorOption.
92
+ func WithAbortEarlyOnErrorOption () WaitForStateOption {
93
+ return & AbortEarlyOnErrorOption {
94
+ abortEarlyOnError : true ,
95
+ }
96
+ }
97
+
79
98
// WaitForState waits for the state machine to reach the given state.
80
99
// If the optional initialWait parameter is set, the function will wait for
81
100
// the given duration before checking the state. This is useful if the
@@ -105,7 +124,8 @@ func (s *CachedObserver) WaitForState(ctx context.Context,
105
124
defer cancel ()
106
125
107
126
// Channel to notify when the desired state is reached
108
- ch := make (chan struct {})
127
+ // or an error occurred.
128
+ ch := make (chan error )
109
129
110
130
// Goroutine to wait on condition variable
111
131
go func () {
@@ -115,8 +135,26 @@ func (s *CachedObserver) WaitForState(ctx context.Context,
115
135
for {
116
136
// Check if the last state is the desired state
117
137
if s .lastNotification .NextState == state {
118
- ch <- struct {}{}
119
- return
138
+ select {
139
+ case <- timeoutCtx .Done ():
140
+ return
141
+
142
+ case ch <- nil :
143
+ return
144
+ }
145
+ }
146
+
147
+ // Check if an error occurred
148
+ if s .lastNotification .Event == OnError {
149
+ if options .abortEarlyOnError {
150
+ select {
151
+ case <- timeoutCtx .Done ():
152
+ return
153
+
154
+ case ch <- s .lastNotification .LastActionError :
155
+ return
156
+ }
157
+ }
120
158
}
121
159
122
160
// Otherwise, wait for the next notification
@@ -130,7 +168,11 @@ func (s *CachedObserver) WaitForState(ctx context.Context,
130
168
return NewErrWaitingForStateTimeout (
131
169
state , s .lastNotification .NextState ,
132
170
)
133
- case <- ch :
171
+
172
+ case lastActionErr := <- ch :
173
+ if lastActionErr != nil {
174
+ return lastActionErr
175
+ }
134
176
return nil
135
177
}
136
178
}
0 commit comments