{"record":{"id":"efb23ab792892336","repo":"pot-app/pot-desktop","slug":"result-message","errorCode":null,"errorMessage":"${result['message']}","messagePattern":"\\$\\{result\\['message'\\]\\}","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/window/Config/pages/Backup/utils/aliyun.jsx","lineNumber":56,"sourceCode":"            drive_id,\n            parent_file_id: dir_id,\n            type: 'file',\n            order_by: 'name',\n        }),\n    });\n    if (res.ok) {\n        const result = res.data;\n        if (result['items']) {\n            return result['items'].map((item) => {\n                return item['name'];\n            });\n        } else {\n            throw new Error(`Get File List Error: ${JSON.stringify(result)}`);\n        }\n    } else {\n        const result = res.data;\n        if (result['message']) {\n            throw new Error(result['message']);\n        } else {\n            throw new Error(`Get accessToken Error: ${JSON.stringify(result)}`);\n        }\n    }\n}\n\nexport async function get(token, name) {\n    const drive_id = await driveId(token);\n    const file_id = await getFileByPath(token, drive_id, name);\n    const url = await getDownloadUrl(token, drive_id, file_id);\n    await invoke('aliyun', { operate: 'get', path: '', url });\n}\n\nexport async function remove(token, name) {\n    const drive_id = await driveId(token);\n    const file_id = await getFileByPath(token, drive_id, name);\n    const res = await fetch('https://openapi.alipan.com/adrive/v1.0/openFile/delete', {\n        method: 'POST',","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/pot-app/pot-desktop/blob/594d32ede96acd106b0256deaa8bb440ffcdff40/src/window/Config/pages/Backup/utils/aliyun.jsx#L38-L74","documentation":"In the aliyun backup `list` function, when the openFile/list API returns a non-2xx status AND the response body contains a `message` field, that server-provided message is thrown verbatim. This surfaces the actual Aliyun Drive API error (auth, permission, parameter problems) directly to the caller.","triggerScenarios":"list(token) receives an HTTP error response from https://openapi.alipan.com/adrive/v1.0/openFile/list whose body has a `message` field — e.g. 401 AccessTokenInvalid/AccessTokenExpired, 403 permission denied, 400 bad drive_id.","commonSituations":"The saved alipan OAuth access token expired (they are short-lived), the token was revoked after re-login, or the app lost the file:all:read scope needed to list files.","solutions":["If the message says the token is invalid/expired, redo the QR-code OAuth flow (qrcode() + status() + accessToken()) to get a fresh token.","Check the message for scope/permission errors and re-authorize with the required scopes (user:base, file:all:read, file:all:write).","Verify the token is actually stored in the backup config — an empty/undefined token yields 401.","If the token is an old refresh token from a previous app version, re-link the account."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function hasToken(config) {\n  return typeof config.aliyunToken === 'string' && config.aliyunToken.length > 20;\n}\n// before calling list():\nif (!hasToken(backupConfig)) openRelinkFlow();","typeGuard":"function isAliyunApiError(body) {\n  return body != null && typeof body === 'object' && typeof body.message === 'string';\n}","tryCatchPattern":"try {\n  const names = await list(token);\n} catch (e) {\n  const msg = String(e.message);\n  if (/AccessToken.*(Invalid|Expired)|401/i.test(msg)) {\n    await reauthorizeAliyun(); // qrcode -> status -> accessToken flow\n  } else {\n    throw e;\n  }\n}","preventionTips":["Refresh the alipan access token proactively — access tokens are short-lived","Detect 401 messages globally and trigger the QR re-login flow automatically","Store and rotate the refresh token so sessions can be renewed silently","Confirm all required scopes were granted during OAuth (file read/write + user:base)"],"tags":["auth","token-expired","aliyun-drive","oauth"],"backgroundTag":"access-token-expired","analyzedSha":"594d32ede96acd106b0256deaa8bb440ffcdff40","analyzedAt":"2026-09-02T18:12:21.811Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}