{"record":{"id":"2547f2c7b74fd20c","repo":"AlistGo/alist","slug":"message-2547f2","errorCode":null,"errorMessage":"message","messagePattern":"message","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/vtencent/util.go","lineNumber":86,"sourceCode":"\tif callback != nil {\n\t\tcallback(req)\n\t} else {\n\t\treq.SetBody(\"{}\")\n\t}\n\tif resp != nil {\n\t\treq.SetResult(resp)\n\t}\n\tres, err := req.Execute(method, url)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcode := utils.Json.Get(res.Body(), \"Code\").ToInt()\n\tif code != 0 {\n\t\tmessage := utils.Json.Get(res.Body(), \"message\").ToString()\n\t\tif len(message) == 0 {\n\t\t\tmessage = utils.Json.Get(res.Body(), \"msg\").ToString()\n\t\t}\n\t\treturn nil, errors.New(message)\n\t}\n\treturn res.Body(), nil\n}\n\nfunc (d *Vtencent) LoadUser() (string, error) {\n\tapi := \"https://api.vs.tencent.com/SaaS/Account/DescribeAccount\"\n\tres, err := d.request(api, http.MethodPost, func(req *resty.Request) {}, nil)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn utils.Json.Get(res, \"Data\", \"TfUid\").ToString(), nil\n}\n\nfunc (d *Vtencent) GetFiles(dirId string) ([]File, error) {\n\tvar res []File\n\t//offset := 0\n\tfor {\n\t\tapi := \"https://api.vs.tencent.com/PaaS/Material/SearchResource\"","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/vtencent/util.go#L68-L104","documentation":"The vtencent ugcRequest() (UGC upload endpoints, cookie-authenticated) checks the numeric Code field and builds the error from the response's message or msg field. When both are absent, errors.New(\"\") produces an error with an EMPTY message — callers see a blank error. The literal lookup key 'message' is this entry's identifier.","triggerScenarios":"UGC API call (e.g. ApplyUploadUGC, CommitUploadUGC) returning Code != 0 with a body that has neither 'message' nor 'msg' — commonly auth-cookie expiry, expired vodSessionKey, or anti-crawler rejection responses that use a different error envelope.","commonSituations":"Cookie for the vod web console expired (most frequent); Upload session key invalidated because the apply/commit sequence took too long or was retried; Server returning an HTML or differently-shaped JSON error page, leaving message fields empty","solutions":["Update the Cookie addition in the vtencent storage config and re-save","Retry the whole upload flow (fresh ApplyUploadUGC) rather than just the failed commit step","If the error is blank, capture res.Body() (add temporary logging) to see the real response before acting","Check origin/referrer requirements if a WAF-style rejection is suspected"],"exampleFix":"// before\nmessage := utils.Json.Get(res.Body(), \"message\").ToString()\nif len(message) == 0 {\n\tmessage = utils.Json.Get(res.Body(), \"msg\").ToString()\n}\nreturn nil, errors.New(message)\n\n// after\nmessage := utils.Json.Get(res.Body(), \"message\").ToString()\nif len(message) == 0 {\n\tmessage = utils.Json.Get(res.Body(), \"msg\").ToString()\n}\nif len(message) == 0 {\n\tmessage = fmt.Sprintf(\"ugc api error code=%d body=%s\", code, res.Body())\n}\nreturn nil, errors.New(message)","handlingStrategy":"try-catch","validationCode":"// pre-check auth cookie exists before UGC calls\nif strings.TrimSpace(d.Cookie) == \"\" {\n    return errors.New(\"vtencent cookie is empty — update credentials before uploading\")\n}","typeGuard":null,"tryCatchPattern":"_, err := d.ugcRequest(api, http.MethodPost, cb, &out)\nif err != nil {\n    if err.Error() == \"\" {\n        // blank error: log raw body and assume session expiry\n        log.Warn(\"ugcRequest returned empty message; refreshing cookie and retrying once\")\n        return d.ugcRequest(api, http.MethodPost, cb, &out) // once, with fresh cookie\n    }\n    return err\n}","preventionTips":["Never treat an empty error message as actionable — always capture res.Body() for UGC failures","Extend the driver to include the numeric Code in the error text","Keep upload flows short enough to avoid session-key expiry between apply and commit"],"tags":["vtencent","tencent-cloud","ugc-upload","api-error","empty-message"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}