{"record":{"id":"b8fac34a41df4f34","repo":"chenhg5/cc-connect","slug":"dingtalk-proactive-send-request-w","errorCode":null,"errorMessage":"dingtalk: proactive send request: %w","messagePattern":"dingtalk: proactive send request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":1692,"sourceCode":"\t} else {\n\t\treturn fmt.Errorf(\"dingtalk: proactive send requires conversationId (group) or senderStaffId (direct)\")\n\t}\n\n\tbody, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: marshal proactive message: %w\", err)\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, apiURL, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: create proactive request: %w\", err)\n\t}\n\treq.Header.Set(\"Content-Type\", \"application/json\")\n\treq.Header.Set(\"x-acs-dingtalk-access-token\", token)\n\n\tresp, err := p.httpClient.Do(req)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: proactive send request: %w\", err)\n\t}\n\tdefer func() { _ = resp.Body.Close() }()\n\n\trespBody, _ := io.ReadAll(resp.Body)\n\tif resp.StatusCode != http.StatusOK {\n\t\treturn fmt.Errorf(\"dingtalk: proactive send failed: status=%d, body=%s\", resp.StatusCode, string(respBody))\n\t}\n\n\tslog.Debug(\"dingtalk: proactive message sent\", \"api\", apiURL, \"status\", resp.StatusCode)\n\treturn nil\n}\n\nvar atUserIDRegexp = regexp.MustCompile(`@(\\d{4,})`)\n\n// extractAtUserIds extracts @userId patterns from content for DingTalk's atUserIds field.\n// Matches @ followed by numeric DingTalk user IDs (e.g. @194252073827812352).\nfunc extractAtUserIds(content string) []string {\n\tmatches := atUserIDRegexp.FindAllStringSubmatch(content, -1)","sourceCodeStart":1674,"sourceCodeEnd":1710,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L1674-L1710","documentation":"The HTTP transport layer failed while POSTing the proactive message to the DingTalk API. This wraps the client-side network error (DNS failure, connection refused, TLS error, timeout) returned by p.httpClient.Do(req), before any HTTP status is received.","triggerScenarios":"p.httpClient.Do(req) returns a non-nil error for the proactive-send POST — network unreachable, DNS resolution failure, proxy failure, or context deadline exceeded mid-request.","commonSituations":"No internet access or blocked access to api.dingtalk.com (firewall/corporate proxy); proxy misconfiguration in the platform options; request timeout set too low; DingTalk service outage.","solutions":["Check basic connectivity to the DingTalk API host (curl https://api.dingtalk.com) from the host running cc-connect.","If a proxy is configured in the dingtalk platform options, verify the proxy URL, credentials, and that the proxy is reachable.","Inspect the wrapped error (%w): context deadline exceeded → increase the HTTP client timeout; connection refused/proxy → fix network or proxy settings.","Add retry with backoff for transient network failures on this idempotent send path."],"exampleFix":"// before\nerr := p.Send(ctx, rc, msg) // fires once, no timeout budget\n// after\nctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)\ndefer cancel()\nerr := p.Send(ctx, rc, msg)","handlingStrategy":"retry","validationCode":"conn, err := net.DialTimeout(\"tcp\", \"api.dingtalk.com:443\", 3*time.Second)\nif err != nil {\n    slog.Warn(\"dingtalk unreachable\", \"err\", err)\n} else {\n    conn.Close()\n}","typeGuard":null,"tryCatchPattern":"var nerr net.Error\nif errors.As(err, &nerr) && nerr.Timeout() {\n    // retry with backoff\n}\nif err := p.Send(ctx, rc, msg); err != nil {\n    slog.Warn(\"proactive send transport error\", \"err\", err)\n}","preventionTips":["Set a sane HTTP client timeout (5–15s) for the DingTalk client","Whitelist api.dingtalk.com in firewalls/proxies","Configure and test the proxy option before deploying","Add exponential backoff retry for transient errors"],"tags":["dingtalk","network","http-client","proactive-send"],"backgroundTag":"network-request-failed","analyzedSha":"4000b2338aa6e850c99df54f8b0ed6ed7460b401","analyzedAt":"2026-09-06T11:45:09.575Z","contentChangedAt":"2026-09-06T11:45:09.575Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}