{"record":{"id":"fb8c565c56b9ea24","repo":"chenhg5/cc-connect","slug":"s-failed-after-d-retries-w","errorCode":null,"errorMessage":"%s failed after %d retries: %w","messagePattern":"(.+?) failed after (.+?) retries: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/feishu/feishu.go","lineNumber":4232,"sourceCode":"\t\t}\n\t\t// Add jitter: up to +25% of delay to spread out concurrent retries.\n\t\tjitter := time.Duration(rand.Int64N(int64(delay / 4)))\n\t\tactualDelay := delay + jitter\n\t\tslog.Warn(p.tag()+\": transient error, retrying\",\n\t\t\t\"operation\", operation,\n\t\t\t\"attempt\", attempt+1,\n\t\t\t\"max_retries\", maxTransientRetries,\n\t\t\t\"delay\", actualDelay,\n\t\t\t\"error\", lastErr,\n\t\t)\n\t\tselect {\n\t\tcase <-ctx.Done():\n\t\t\treturn fmt.Errorf(\"%s: %s retry cancelled: %w (last error: %v)\", p.tag(), operation, ctx.Err(), lastErr)\n\t\tcase <-time.After(actualDelay):\n\t\t}\n\t\tdelay = min(delay*2, transientRetryMaxDelay)\n\t}\n\treturn fmt.Errorf(\"%s failed after %d retries: %w\", operation, maxTransientRetries, lastErr)\n}\n\n// ── Issue #1618: fail-closed + supervised retry for bot open_id ──\n//\n// When the Feishu/Lark bot-info API call fails at startup (transient\n// proxy/VPN/DNS outage, server hiccup, etc.), the bot's open_id stays\n// unknown. The previous behaviour read this as \"group mention filter\n// off\", so the bot would reply to every group message for the rest of\n// the process lifetime — a 3h10m window in the user's incident where\n// the bot suddenly became a loud responder with no way for operators\n// to notice. The functions below:\n//\n//   - wrap the initial fetch in transient retry so most startup\n//     failures self-heal before we degrade,\n//   - mark the filter as \"degraded\" (rather than \"off\") when the\n//     retry budget is exhausted, with timestamp + last error captured\n//     for /status surface,\n//   - start a background supervisor that retries every","sourceCodeStart":4214,"sourceCodeEnd":4250,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/feishu/feishu.go#L4214-L4250","documentation":"withTransientRetry exhaustion: the operation still failed with a transient error after maxTransientRetries attempts of exponential backoff with up to +25% jitter; the last error is wrapped for the caller.","triggerScenarios":"Thrown at platform/feishu/feishu.go:4232 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Check Feishu API status/incidents and rate limits (429)","Increase retry budget or reduce call frequency"],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}