{"record":{"id":"1e9ca1e09770fa7d","repo":"AlistGo/alist","slug":"dynamic-fmt-errorf-info-message-passthrough-fr","errorCode":null,"errorMessage":"dynamic: fmt.Errorf(info) - message passthrough from API 'inf'/'info' JSON field","messagePattern":"dynamic: fmt\\.Errorf\\(info\\) - message passthrough from API 'inf'/'info' JSON field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"drivers/lanzou/util.go","lineNumber":93,"sourceCode":"\t}, up)\n\tif err != nil {\n\t\treturn data, err\n\t}\n\tswitch utils.Json.Get(data, \"zt\").ToInt() {\n\tcase 1, 2, 4:\n\t\tif resp != nil {\n\t\t\t// 返回类型不统一,忽略错误\n\t\t\tutils.Json.Unmarshal(data, resp)\n\t\t}\n\t\treturn data, nil\n\tcase 9: // 登录过期\n\t\treturn data, ErrCookieExpiration\n\tdefault:\n\t\tinfo := utils.Json.Get(data, \"inf\").ToString()\n\t\tif info == \"\" {\n\t\t\tinfo = utils.Json.Get(data, \"info\").ToString()\n\t\t}\n\t\treturn data, fmt.Errorf(info)\n\t}\n}\n\nfunc (d *LanZou) request(url string, method string, callback base.ReqCallback, up bool) ([]byte, error) {\n\tvar client *resty.Client\n\tif up {\n\t\tonce.Do(func() {\n\t\t\tupClient = base.NewRestyClient().SetTimeout(120 * time.Second)\n\t\t})\n\t\tclient = upClient\n\t} else {\n\t\tclient = base.RestyClient\n\t}\n\n\t// acw_sc__v2 反爬挑战可能出现在任意页面/接口(分享页、iframe 页、ajaxm.php 等)。\n\t// 挑战页内嵌 arg1,需据此算出 cookie 后用同一请求重试,故在最底层统一处理。\n\tvar acwScV2 string\n\tvar body []byte","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/AlistGo/alist/blob/843d9dc8149126976b2625911e45a4d3ffd6f2f5/drivers/lanzou/util.go#L75-L111","documentation":"Dynamic application-level error from the LanZou _post layer: when the response JSON's zt code is not 1/2/4 (success/retry) and not 9 (cookie expiration), the driver surfaces the server's own message from the 'inf' or 'info' JSON field via fmt.Errorf(info). The error text is therefore whatever LanZou reported.","triggerScenarios":"Any LanZou AJAX endpoint returning a non-success zt: file not found, wrong share password, 'file is canceled' / 'file does not exist' style messages, or rate-limit responses — everything except the dedicated zt==9 expiry path.","commonSituations":"Expired/deleted share links; wrong or missing share password; heavy usage triggering LanZou anti-abuse; folder ID no longer accessible to the account.","solutions":["Read the message itself — it is LanZou's own reason and usually decisive (e.g. wrong password, file deleted)","If it mentions password, supply/correct the share password in the driver or link config","If it mentions deletion/invalidity, remove or fix the affected share link","Slow down request rates if the message indicates abuse control"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// driver-internal pattern already: zt==9 maps to ErrCookieExpiration with auto re-login;\n// callers should key on sentinel errors first\nif err := d.post(url, cb, &resp); err != nil {\n    if errors.Is(err, ErrCookieExpiration) { /* handled by post() retry */ }\n    // otherwise err.Error() IS lanzou's own 'inf'/'info' message\n}","preventionTips":["Handle ErrCookieExpiration distinctly — it triggers automatic re-login for account mode","Map known passthrough texts (wrong password, file deleted) to user-friendly actions","Throttle requests to avoid anti-abuse zt responses"],"tags":["lanzou","api-error","passthrough","share-link","openlist"],"backgroundTag":null,"analyzedSha":"843d9dc8149126976b2625911e45a4d3ffd6f2f5","analyzedAt":"2026-08-15T12:14:11.722Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}