{"record":{"id":"eb52de5d6862a679","repo":"siyuan-note/siyuan","slug":"conf-language-298","errorCode":null,"errorMessage":"Conf.Language(298)","messagePattern":"Conf\\.Language\\(298\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"kernel/model/cloud_service.go","lineNumber":136,"sourceCode":"\trequest := httpclient.NewCloudRequest30s()\n\tresp, err := request.\n\t\tSetSuccessResult(requestResult).\n\t\tSetCookies(&http.Cookie{Name: \"symphony\", Value: user.UserToken}).\n\t\tPost(util.GetCloudServer() + \"/apis/siyuan/user/startFreeTrial\")\n\tif err != nil {\n\t\tlogging.LogErrorf(\"start free trial failed: %s\", err)\n\t\treturn ErrFailedToConnectCloudServer\n\t}\n\tif http.StatusUnauthorized == resp.StatusCode {\n\t\tinvalidUser()\n\t\treturn errors.New(Conf.Language(31))\n\t}\n\tif http.StatusOK != resp.StatusCode {\n\t\tlogging.LogErrorf(\"start free trial failed: %d\", resp.StatusCode)\n\t\treturn ErrFailedToConnectCloudServer\n\t}\n\tif -2 == requestResult.Code { // 已经试用订阅过\n\t\treturn errors.New(Conf.Language(298))\n\t}\n\tif 0 != requestResult.Code {\n\t\treturn errors.New(requestResult.Msg)\n\t}\n\treturn\n}\n\nfunc DeactivateUser() (err error) {\n\trelease := lockAssetSourceChange()\n\tdefer release()\n\tif Conf.Sync.Provider == conf.ProviderSiYuan {\n\t\tif err = requireCompleteAssetDownloads(); err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\tuser := Conf.GetUser()\n\tif user == nil {\n\t\treturn errors.New(Conf.Language(31))","sourceCodeStart":118,"sourceCodeEnd":154,"githubUrl":"https://github.com/siyuan-note/siyuan/blob/8641553a1f07374001902d3ce773285db1292b2d/kernel/model/cloud_service.go#L118-L154","documentation":"StartFreeTrial checks the cloud business result code after an HTTP 200 response: code -2 means the account has already used the free trial, and the function returns the localized 'free trial already used' message Conf.Language(298). It is an expected, user-facing business outcome rather than a fault.","triggerScenarios":"Calling startFreeTrial with a cloud account whose free trial subscription has already been activated at any point in the past.","commonSituations":"User previously started the trial (possibly on another device under the same account) and later attempts to start it again; retrying the trial action after an earlier successful attempt that the user forgot.","solutions":["Inform the user the trial was already consumed and offer a paid subscription instead (Settings - Account - Subscribe)","Check the subscription status via the account panel before offering the trial button","Treat code -2 as informational, not an error needing retry — retrying will always return -2"],"exampleFix":"// before\nerr := model.StartFreeTrial()\nshowMessage(err.Error())\n// after\nerr := model.StartFreeTrial()\nif err != nil && err.Error() == Conf.Language(298) {\n    openSubscriptionPanel() // trial already used\n    return\n}\nif err != nil { showMessage(err.Error()) }","handlingStrategy":"fallback","validationCode":"// check subscription state via the account panel before offering the trial\nconst trialUsed = window.siyuan.user && window.siyuan.user.trialUsed;","typeGuard":null,"tryCatchPattern":"err := model.StartFreeTrial()\nif err != nil && err.Error() == Conf.Language(298) {\n    openSubscriptionPanel() // offer paid plan; do not retry\n}","preventionTips":["Hide the trial button once the account has consumed its trial","Treat code -2 as a terminal business state — never retry","Offer the paid subscription path as the follow-up action"],"tags":["cloud","subscription","business-rule"],"backgroundTag":"api-error-response","analyzedSha":"8641553a1f07374001902d3ce773285db1292b2d","analyzedAt":"2026-09-11T16:08:28.414Z","contentChangedAt":"2026-09-11T16:08:28.414Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}