Skip to content

[FRT-1629] Dedupe retryable statement errors and always surface a failure reason#3400

Draft
Natea Eshetu Beshada (nateab) wants to merge 1 commit into
mainfrom
FRT-1629
Draft

[FRT-1629] Dedupe retryable statement errors and always surface a failure reason#3400
Natea Eshetu Beshada (nateab) wants to merge 1 commit into
mainfrom
FRT-1629

Conversation

@nateab

Copy link
Copy Markdown
Member

Problem

confluent flink statement error output is confusing when a statement fails during the brief PENDING window (surfaced via CREATE FUNCTION on an unsupported PTF state type, but general):

  • A retryable status.detail is appended once per poll and printed N× — e.g. captured retryable errors: <msg>; <msg>; … alongside exiting after 6 retries.
  • A FAILED statement with an empty status.detail prints a bare can't fetch results. Statement phase is: FAILED with no reason.

Change (pkg/flink/internal/store)

  • Dedupe captured retryable details via a new formatCapturedErrors helper — identical details collapse to a single line annotated (repeated N times); used at both the retry-limit and timeout exits.
  • Always surface a FAILED reason in WaitPendingStatement: when status.detail is empty (and no exceptions are available), emit a clear placeholder pointing at confluent flink statement describe, plus an actionable Suggestion. Mirrored to the on-prem store.

Tests

  • Updated TestWaitForPendingHitsErrorRetryLimit for the deduped output.
  • Added TestWaitPendingStatementSetsPlaceholderWhenFailedWithNoReason.
  • Added Suggestion assertions to the existing FAILED-branch tests.
  • go test ./pkg/flink/internal/store/, gofmt, and go vet clean locally.

Context

The originally-suspected server-side "statement stuck ~2 min" behavior was investigated and measured on devel: deterministic UDF extraction errors already fast-fail (~15s) via the control-plane expire-now path, so no server-side change is needed. This PR addresses the residual CLI-output issue. Details in FRT-1629.

Refs FRT-1629.

Copilot AI review requested due to automatic review settings July 8, 2026 23:00
@confluent-cla-assistant

Copy link
Copy Markdown

🎉 All Contributor License Agreements have been signed. Ready to merge.
Please push an empty commit if you would like to re-run the checks to verify CLA status for all contributors.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Improves confluent flink statement failure UX by reducing noisy repeated retryable error details during PENDING polling and ensuring terminal failures surface a meaningful reason (or a clear placeholder) along with an actionable suggestion.

Changes:

  • Added formatCapturedErrors to de-duplicate repeated retryable status.detail messages and use it at retry-limit and timeout exits.
  • Updated WaitPendingStatement (cloud + on-prem) to always return a non-empty failure reason for terminal states and to include a Suggestion.
  • Updated/added unit tests to cover deduped output and FAILED-with-no-reason behavior.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.

File Description
pkg/flink/internal/store/store.go Adds failure-reason placeholder + suggestion for terminal states; dedupes retryable errors via formatCapturedErrors.
pkg/flink/internal/store/store_onprem.go Mirrors the terminal-state failure-reason placeholder + suggestion behavior for on-prem.
pkg/flink/internal/store/store_test.go Updates retry-limit expectation; adds coverage for FAILED with no status.detail/exceptions and asserts Suggestion.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

if statementStatus != types.COMPLETED && statementStatus != types.RUNNING {
failureMessage := updatedStatement.StatusDetail
if failureMessage == "" {
failureMessage = fmt.Sprintf("the server did not report a failure reason; run `confluent flink statement describe %s` for the full status", statement.StatementName)
if statementStatus != types.COMPLETED && statementStatus != types.RUNNING {
failureMessage := updatedStatement.StatusDetail
if failureMessage == "" {
failureMessage = fmt.Sprintf("the server did not report a failure reason; run `confluent flink statement describe %s` for the full status", statement.StatementName)
@sonarqube-confluent

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants