{"record":{"id":"fea10edd0767d3eb","repo":"t8y2/dbx","slug":"xugu-operation-canceled","errorCode":null,"errorMessage":"xugu operation canceled","messagePattern":"xugu operation canceled","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"info","filePath":"agents/drivers/xugu/protocol_error.go","lineNumber":20,"sourceCode":"\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"database/sql/driver\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"net\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n)\n\nvar (\n\terrAgentSessionLimit     = errors.New(\"agent session limit reached\")\n\terrAgentSessionNotFound  = errors.New(\"agent session not found\")\n\terrXuguOperationTimeout  = errors.New(\"xugu operation timed out\")\n\terrXuguOperationCanceled = errors.New(\"xugu operation canceled\")\n\n\t// go-xugu-driver exposes server errors as plain strings rather than a typed\n\t// error. Match only the stable server error header and keep the complete\n\t// original message for diagnostics. A response can contain more than one\n\t// Xugu error; vendorCode intentionally records the first/top-level code.\n\txuguServerErrorHeader = regexp.MustCompile(`(?im)^[\\t ]*(?:error:[\\t ]*)?\\[[\\t ]*E([0-9]{1,9})(?:[\\t ]+L([0-9]+))?(?:[\\t ]+C([0-9]+))?[\\t ]*\\]`)\n\txuguQueryTimeout      = regexp.MustCompile(`(?i)^query timed out after [1-9][0-9]*s$`)\n)\n\ntype rpcError struct {\n\tCode    int           `json:\"code\"`\n\tMessage string        `json:\"message\"`\n\tData    *rpcErrorData `json:\"data,omitempty\"`\n}\n\ntype rpcErrorData struct {\n\tCategory           string `json:\"category\"`\n\tRetryable          bool   `json:\"retryable\"`","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/t8y2/dbx/blob/c0390bff16418b651f4728520d99adf8ce48829a/agents/drivers/xugu/protocol_error.go#L2-L38","documentation":"errXuguOperationCanceled is a sentinel error returned by classifyRPCError when the Xugu driver reports the operation was canceled (e.g. context cancellation) rather than timed out. It is returned directly, or wrapped with the underlying operation error via %w, preserving errors.Is matching.","triggerScenarios":"classifyRPCError sets canceled and main.go:4326-4328 returns errXuguOperationCanceled (optionally wrapped with the underlying error) when the driver signals cancellation — typically the caller's context was canceled/closed mid-operation.","commonSituations":"User cancels a query in the UI, HTTP request context is canceled while a query runs, application shutdown closes the context, an upstream deadline fires before the Xugu timeout.","solutions":["Identify what canceled the context (upstream deadline, user abort, shutdown) via the wrapped operationErr","Only cancel contexts when the result is genuinely no longer needed","For operations that must complete, use context.WithoutCancel or a detached context","Distinguish cancellation from timeout in code with errors.Is(err, errXuguOperationCanceled)","Re-issue the operation if cancellation was accidental"],"exampleFix":"// before\nrows, err := conn.Query(ctx, q) // ctx canceled by HTTP client disconnect\n// after\nrows, err := conn.Query(context.WithoutCancel(ctx), q)\nif errors.Is(err, errXuguOperationCanceled) { /* graceful cleanup */ }","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"func IsXuguOperationCanceled(err error) bool {\n    return errors.Is(err, errXuguOperationCanceled)\n}","tryCatchPattern":"rows, err := conn.Query(ctx, q)\nif errors.Is(err, errXuguOperationCanceled) {\n    // context was canceled: clean up quietly, do not retry with the same ctx\n    return ctx.Err()\n}","preventionTips":["Pass explicit, purpose-scoped contexts to long-running Xugu operations","Avoid sharing request contexts with background/batch work that must finish","Use context.WithoutCancel for operations that should survive caller abort","Log the wrapped operationErr to identify what triggered cancellation"],"tags":["xugu","cancellation","context","database"],"backgroundTag":"context-canceled","analyzedSha":"c0390bff16418b651f4728520d99adf8ce48829a","analyzedAt":"2026-09-05T23:05:10.900Z","contentChangedAt":"2026-09-05T23:05:10.900Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}