{"record":{"id":"55ffd3312e94bdce","repo":"chenhg5/cc-connect","slug":"dingtalk-emotion-request-w","errorCode":null,"errorMessage":"dingtalk: emotion request: %w","messagePattern":"dingtalk: emotion request: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"platform/dingtalk/dingtalk.go","lineNumber":961,"sourceCode":"\t\t\tText:         emoji,\n\t\t\tBackgroundID: customTextEmotionBackground,\n\t\t},\n\t}\n\tbody, err := json.Marshal(requestBody)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: marshal emotion request: %w\", err)\n\t}\n\n\treq, err := http.NewRequestWithContext(ctx, http.MethodPost, \"https://api.dingtalk.com\"+path, bytes.NewReader(body))\n\tif err != nil {\n\t\treturn fmt.Errorf(\"dingtalk: create emotion 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: emotion 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: emotion returned status %d: %s\", resp.StatusCode, string(respBody))\n\t}\n\tif len(respBody) == 0 {\n\t\treturn nil\n\t}\n\tvar result struct {\n\t\tSuccess *bool `json:\"success\"`\n\t}\n\tif err := json.Unmarshal(respBody, &result); err == nil && result.Success != nil && !*result.Success {\n\t\treturn fmt.Errorf(\"dingtalk: emotion returned success=false\")\n\t}\n\treturn nil\n}","sourceCodeStart":943,"sourceCodeEnd":979,"githubUrl":"https://github.com/chenhg5/cc-connect/blob/4000b2338aa6e850c99df54f8b0ed6ed7460b401/platform/dingtalk/dingtalk.go#L943-L979","documentation":"This error is returned by sendEmotion when the HTTP client fails to execute the POST to DingTalk's emotion API — i.e. the request never got a response. The wrapped err from p.httpClient.Do carries the real cause: DNS resolution failure, connection refused/reset, TLS error, or the client's 30-second timeout firing. It means the emotion (typing indicator / reaction / recall) could not be delivered due to a transport-level problem, not an API rejection.","triggerScenarios":"p.httpClient.Do(req) returns an error during sendEmotion — network outage, DNS failure for api.dingtalk.com, connection reset by a proxy/firewall, TLS handshake failure, or the 30s client timeout elapsing on a hung connection.","commonSituations":"Server hosting cc-connect lost internet or has a firewall blocking api.dingtalk.com; corporate proxy requiring configuration; slow network causing the 30-second timeout; transient DingTalk-side connection resets.","solutions":["Check outbound connectivity from the host: curl -v https://api.dingtalk.com/v1.0/robot/emotion/reply","Verify DNS resolves api.dingtalk.com on the host","Check proxy/firewall rules; set HTTPS_PROXY if the host requires a proxy","If timeouts recur, investigate network latency between the host and api.dingtalk.com (client timeout is fixed at 30s)","Simply retry — transient connection resets are common"],"exampleFix":"// environment check\n// before: connection silently fails behind corporate proxy\n// after: export proxy so Go's http client uses it\nexport HTTPS_PROXY=http://proxy.corp.local:8080","handlingStrategy":"retry","validationCode":"// Go: check outbound reachability before relying on emotion features\nresp, err := http.Head(\"https://api.dingtalk.com\")\nif err != nil {\n    return fmt.Errorf(\"dingtalk unreachable: %w\", err)\n}\nresp.Body.Close()","typeGuard":null,"tryCatchPattern":"err := p.StartTyping(ctx, rctx)\nfor i := 0; i < 3 && err != nil; i++ {\n    if errors.Is(err, context.DeadlineExceeded) || isNetErr(err) {\n        time.Sleep(time.Duration(1<<i) * time.Second)\n        err = p.StartTyping(ctx, rctx)\n        continue\n    }\n    break\n}","preventionTips":["Ensure the host has reliable egress to api.dingtalk.com (firewall/proxy rules)","Configure HTTPS_PROXY where a corporate proxy is required","Monitor DNS health on the host; pin known-good resolvers","Treat typing indicators as best-effort — never fail the main message flow over them"],"tags":["dingtalk","network","http","timeout"],"backgroundTag":"request-timeout","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"}