@@ -109,8 +109,12 @@ func (r *Reconciler) Reconcile(ctx context.Context, req runtime.Request) (runtim
109109 return runtime.Result {}, err
110110 }
111111
112+ // Track errors for metrics emission. The error is used to determine the failure type
113+ // (user_error vs internal_error) in the emitted metrics.
114+ var reconcileErr error
112115 // Emit the update run status metric based on status conditions in the updateRun.
113- defer emitUpdateRunStatusMetric (updateRun )
116+ // Use a closure to capture reconcileErr by reference, so it reflects any updates made during reconciliation.
117+ defer func () { emitUpdateRunStatusMetric (updateRun , reconcileErr ) }()
114118
115119 state := updateRun .GetUpdateRunSpec ().State
116120
@@ -126,14 +130,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, req runtime.Request) (runtim
126130 }
127131
128132 // Initialize the updateRun.
129- var initErr error
130- if toBeUpdatedBindings , toBeDeletedBindings , initErr = r .initialize (ctx , updateRun ); initErr != nil {
131- klog .ErrorS (initErr , "Failed to initialize the updateRun" , "updateRun" , runObjRef )
133+ if toBeUpdatedBindings , toBeDeletedBindings , reconcileErr = r .initialize (ctx , updateRun ); reconcileErr != nil {
134+ klog .ErrorS (reconcileErr , "Failed to initialize the updateRun" , "updateRun" , runObjRef )
132135 // errStagedUpdatedAborted cannot be retried.
133- if errors .Is (initErr , errStagedUpdatedAborted ) {
134- return runtime.Result {}, r .recordInitializationFailed (ctx , updateRun , initErr .Error ())
136+ if errors .Is (reconcileErr , errStagedUpdatedAborted ) {
137+ return runtime.Result {}, r .recordInitializationFailed (ctx , updateRun , reconcileErr .Error ())
135138 }
136- return runtime.Result {}, initErr
139+ return runtime.Result {}, reconcileErr
137140 }
138141 updatingStageIndex = 0 // start from the first stage (typically for Initialize or Run states).
139142 klog .V (2 ).InfoS ("Initialized the updateRun" , "state" , state , "updateRun" , runObjRef )
@@ -145,14 +148,13 @@ func (r *Reconciler) Reconcile(ctx context.Context, req runtime.Request) (runtim
145148 klog .V (2 ).InfoS ("The updateRun is finished" , "finishedSuccessfully" , finishedCond .Status , "updateRun" , runObjRef )
146149 return runtime.Result {}, nil
147150 }
148- var validateErr error
149151 // Validate the updateRun status to ensure the update can be continued and get the updating stage index and cluster indices.
150- if updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings , validateErr = r .validate (ctx , updateRun ); validateErr != nil {
152+ if updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings , reconcileErr = r .validate (ctx , updateRun ); reconcileErr != nil {
151153 // errStagedUpdatedAborted cannot be retried.
152- if errors .Is (validateErr , errStagedUpdatedAborted ) {
153- return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , validateErr .Error ())
154+ if errors .Is (reconcileErr , errStagedUpdatedAborted ) {
155+ return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , reconcileErr .Error ())
154156 }
155- return runtime.Result {}, validateErr
157+ return runtime.Result {}, reconcileErr
156158 }
157159 klog .V (2 ).InfoS ("The updateRun is validated" , "updateRun" , runObjRef )
158160 }
@@ -163,45 +165,48 @@ func (r *Reconciler) Reconcile(ctx context.Context, req runtime.Request) (runtim
163165 return runtime.Result {}, r .recordUpdateRunSucceeded (ctx , updateRun )
164166 }
165167
168+ var finished bool
169+ var waitTime time.Duration
166170 switch state {
167171 case placementv1beta1 .StateInitialize :
168172 klog .V (2 ).InfoS ("The updateRun is initialized but not executed, waiting to execute" , "state" , state , "updateRun" , runObjRef )
169173 case placementv1beta1 .StateRun :
170174 // Execute the updateRun.
171175 klog .V (2 ).InfoS ("Continue to execute the updateRun" , "updatingStageIndex" , updatingStageIndex , "updateRun" , runObjRef )
172- finished , waitTime , execErr : = r .execute (ctx , updateRun , updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings )
173- if errors .Is (execErr , errStagedUpdatedAborted ) {
176+ finished , waitTime , reconcileErr = r .execute (ctx , updateRun , updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings )
177+ if errors .Is (reconcileErr , errStagedUpdatedAborted ) {
174178 // errStagedUpdatedAborted cannot be retried.
175- return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , execErr .Error ())
179+ return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , reconcileErr .Error ())
176180 }
177181
178182 if finished {
179183 klog .V (2 ).InfoS ("The updateRun is completed" , "updateRun" , runObjRef )
180184 return runtime.Result {}, r .recordUpdateRunSucceeded (ctx , updateRun )
181185 }
182186
183- return r .handleIncompleteUpdateRun (ctx , updateRun , waitTime , execErr , state , runObjRef )
187+ return r .handleIncompleteUpdateRun (ctx , updateRun , waitTime , reconcileErr , state , runObjRef )
184188 case placementv1beta1 .StateStop :
185189 // Stop the updateRun.
186190 klog .V (2 ).InfoS ("Stopping the updateRun" , "state" , state , "updatingStageIndex" , updatingStageIndex , "updateRun" , runObjRef )
187- finished , waitTime , stopErr : = r .stop (updateRun , updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings )
188- if errors .Is (stopErr , errStagedUpdatedAborted ) {
191+ finished , waitTime , reconcileErr = r .stop (updateRun , updatingStageIndex , toBeUpdatedBindings , toBeDeletedBindings )
192+ if errors .Is (reconcileErr , errStagedUpdatedAborted ) {
189193 // errStagedUpdatedAborted cannot be retried.
190- return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , stopErr .Error ())
194+ return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , reconcileErr .Error ())
191195 }
192196
193197 if finished {
194198 klog .V (2 ).InfoS ("The updateRun is stopped" , "updateRun" , runObjRef )
195199 return runtime.Result {}, r .recordUpdateRunStopped (ctx , updateRun )
196200 }
197201
198- return r .handleIncompleteUpdateRun (ctx , updateRun , waitTime , stopErr , state , runObjRef )
202+ return r .handleIncompleteUpdateRun (ctx , updateRun , waitTime , reconcileErr , state , runObjRef )
199203
200204 default :
201205 // Initialize, Run, or Stop are the only supported states.
202- unexpectedErr := controller .NewUnexpectedBehaviorError (fmt .Errorf ("found unsupported updateRun state: %s" , state ))
203- klog .ErrorS (unexpectedErr , "Invalid updateRun state" , "state" , state , "updateRun" , runObjRef )
204- return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , unexpectedErr .Error ())
206+ reconcileErr = controller .NewUnexpectedBehaviorError (fmt .Errorf ("found unsupported updateRun state: %s" , state ))
207+ klog .ErrorS (reconcileErr , "Invalid updateRun state" , "state" , state , "updateRun" , runObjRef )
208+ // This is an internal error - unsupported state should not happen
209+ return runtime.Result {}, r .recordUpdateRunFailed (ctx , updateRun , reconcileErr .Error ())
205210 }
206211 return runtime.Result {}, nil
207212}
0 commit comments