MCPcopy Index your code
hub / github.com/coder/coder / finish

Method finish

coderd/x/chatd/chatdebug/recorder.go:295–366  ·  view source on GitHub ↗

finish updates the debug step with final status and data. A mutex guards the write so concurrent callers (e.g. retried stream wrappers sharing a reuse handle) don't race. Later retries are allowed to overwrite earlier failure results so the step reflects the final outcome, but stale callbacks cann

(
	ctx context.Context,
	status Status,
	response any,
	usage any,
	errPayload any,
	metadata any,
)

Source from the content-addressed store, hash-verified

293// overwrite earlier failure results so the step reflects the final
294// outcome, but stale callbacks cannot regress a terminal state.
295func (h *stepHandle) finish(
296 ctx context.Context,
297 status Status,
298 response any,
299 usage any,
300 errPayload any,
301 metadata any,
302) {
303 if h == nil || h.stepCtx == nil {
304 return
305 }
306
307 h.mu.Lock()
308 defer h.mu.Unlock()
309
310 // Reject stale callbacks that would regress a terminal state.
311 // Status priority: in_progress < interrupted < error < completed.
312 // A tardy safety-net writing "interrupted" cannot clobber a step
313 // that already reached "completed" or "error" from a real retry.
314 // Equal-priority updates are allowed so that retries ending in the
315 // same terminal class (e.g. error → error under ReuseStep) can
316 // still update the step with newer attempt data.
317 if h.status.IsTerminal() && status.Priority() < h.status.Priority() {
318 return
319 }
320
321 h.status = status
322 h.response = response
323 h.usage = usage
324 h.err = errPayload
325 h.metadata = metadata
326 if errPayload != nil {
327 h.hadError = true
328 }
329 if h.svc == nil {
330 return
331 }
332
333 updateCtx, cancel := stepFinalizeContext(ctx)
334 defer cancel()
335
336 // When the step completes successfully after a prior failed
337 // attempt, the error field must be explicitly cleared. A plain
338 // nil would leave the COALESCE-based SQL untouched, so we send
339 // jsonClear{} which serializes as a valid JSONB null. Only do
340 // this when a prior error was actually recorded; otherwise
341 // clean successes would get a spurious JSONB null that downstream
342 // aggregation could misread as an error.
343 errValue := errPayload
344 if errValue == nil && status == StatusCompleted && h.hadError {
345 errValue = jsonClear{}
346 }
347
348 if _, updateErr := h.svc.UpdateStep(updateCtx, UpdateStepParams{
349 ID: h.stepCtx.StepID,
350 ChatID: h.stepCtx.ChatID,
351 Status: status,
352 NormalizedResponse: response,

Callers 9

GenerateMethod · 0.80
StreamMethod · 0.80
GenerateObjectMethod · 0.80
StreamObjectMethod · 0.80
wrapStreamSeqFunction · 0.80
wrapObjectStreamSeqFunction · 0.80
RunFunction · 0.80
createTemplateVersionTarFunction · 0.80

Calls 8

stepFinalizeContextFunction · 0.85
IsTerminalMethod · 0.80
PriorityMethod · 0.80
UpdateStepMethod · 0.80
snapshotMethod · 0.80
LockMethod · 0.45
UnlockMethod · 0.45
ErrorMethod · 0.45

Tested by 1