t8y2/dbx · error · errXuguOperationTimeout

%w after %ds: %v

Error message

%w after %ds: %v

What it means

xuguOperationResultError wraps errXuguOperationTimeout ('xugu operation timed out') with the timeout duration and the underlying error using %w so errors.Is/As work. It is returned when an asynchronous XuguDB operation (query, DDL, etc.) exceeded the configured timeout and the wait also produced an error (e.g. context deadline or driver failure).

Source

Thrown at agents/drivers/xugu/main.go:4320

	s.activeCancelMu.Lock()
	s.activeCancel = nil
	if s.activeTimer != nil {
		s.activeTimer.Stop()
		s.activeTimer = nil
	}
	timedOut := s.activeTimedOut
	canceled := s.activeCanceled
	s.activeTimedOut = false
	s.activeCanceled = false
	s.activeCancelMu.Unlock()
	cancel()
	return xuguOperationResultError(timedOut, canceled, timeoutSecs, operationErr)
}

func xuguOperationResultError(timedOut, canceled bool, timeoutSecs int, operationErr error) error {
	if timedOut {
		if operationErr != nil {
			return fmt.Errorf("%w after %ds: %v", errXuguOperationTimeout, timeoutSecs, operationErr)
		}
		return fmt.Errorf("%w after %ds", errXuguOperationTimeout, timeoutSecs)
	}
	if canceled {
		if operationErr != nil {
			return fmt.Errorf("%w: %v", errXuguOperationCanceled, operationErr)
		}
		return errXuguOperationCanceled
	}
	return operationErr
}

func (s *server) cancelActiveQuery() {
	s.activeCancelMu.Lock()
	cancels := make([]context.CancelFunc, 0, len(s.activeRows)+1)
	if s.activeCancel != nil {
		if !s.activeTimedOut {
			s.activeCanceled = true

View on GitHub (pinned to c0390bff16)

Solutions

  1. Check the wrapped %v cause: it usually reveals whether the context deadline or a network issue fired.
  2. Increase the operation timeout (timeoutSecs) for legitimately long operations.
  3. Optimize or kill the blocking statement (check for lock contention with catalog/lock views).
  4. Check network stability and server health; retry the operation once the cause is addressed.

Example fix

// before: default 30s timeout on a big rebuild
res, err := client.ExecuteWait(ddl, 30)

// after: allow longer for heavy DDL
res, err := client.ExecuteWait(ddl, 600)
Defensive patterns

Strategy: retry

Validate before calling

// estimate runtime first
var cost int64
db.QueryRow(`SELECT COUNT(*) FROM ALL_TABLES WHERE TABLE_NAME=?`, table).Scan(&cost)
if cost > largeThreshold { timeoutSecs = 600 } // pick timeout proportional to size

Try / catch

if errors.Is(err, errXuguOperationTimeout) {
    var toerr *TimeoutWithCause
    if errors.As(err, &toerr) { log.Errorf("timed out after %ds: %v", toerr.Seconds, toerr.Cause) }
    return retryWithBackoff(op, longerTimeout)
}

Prevention

When it happens

Trigger: A long-running statement or operation exceeds timeoutSecs while polling its result, and operationErr is non-nil — e.g. the context deadline fired or the connection broke during the wait.

Common situations: Slow queries on large tables; server-side blocking (locks); network stalls; timeout configured too low for maintenance DDL like index builds; server overload.

Related errors


AI-assisted analysis of t8y2/dbx@c0390bff16 (2026-09-05). Data as JSON: /api/errors/8b83d11edba40c66. Report an issue: GitHub.