{"record":{"id":"4e11c110cdc54011","repo":"pot-app/pot-desktop","slug":"can-not-find-url-json-stringify-result","errorCode":null,"errorMessage":"Can not find url: ${JSON.stringify(result)}","messagePattern":"Can not find url: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/window/Config/pages/Backup/utils/aliyun.jsx","lineNumber":321,"sourceCode":"}\n\nasync function getDownloadUrl(token, drive_id, file_id) {\n    const res = await fetch('https://openapi.alipan.com/adrive/v1.0/openFile/getDownloadUrl', {\n        method: 'POST',\n        headers: {\n            Authorization: `Bearer ${token}`,\n        },\n        body: Body.json({\n            drive_id,\n            file_id,\n        }),\n    });\n    if (res.ok) {\n        const result = res.data;\n        if (result['url']) {\n            return result['url'];\n        } else {\n            throw new Error(`Can not find url: ${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","sourceCodeStart":303,"sourceCodeEnd":332,"githubUrl":"https://github.com/pot-app/pot-desktop/blob/594d32ede96acd106b0256deaa8bb440ffcdff40/src/window/Config/pages/Backup/utils/aliyun.jsx#L303-L332","documentation":"getDownloadUrl calls the Alipan openAPI endpoint openFile/getDownloadUrl. If the HTTP response is ok (2xx) but the body does not contain a 'url' field, this error is thrown with the whole payload JSON-stringified. A 2xx response without 'url' means the API accepted the request semantics but did not return a download link (unusual response shape or partial success payload).","triggerScenarios":"getDownloadUrl receives res.ok === true but result['url'] is undefined: e.g. the API returns a success envelope without a url because file_id exists in a different drive, the file is in recycle bin, or the response schema changed / is an error object delivered with a 2xx-wrapped body.","commonSituations":"Passing a file_id obtained from a different drive than drive_id; file was moved to trash so download link is withheld; Alipan API response schema update; incorrect parsing layer (res.data already unwrapped differently than expected by the HTTP client).","solutions":["Log the JSON.stringify(result) embedded in the error to see the actual payload keys returned by the API.","Confirm drive_id and file_id are a matching pair (fetch file_id with getFileByPath on the same drive_id).","Check whether the file is in the recycle bin and restore it, or re-upload the backup.","Update parsing to the current Alipan openAPI response schema if it changed.","Retry; if the API occasionally returns envelopes without url, treat missing url as retryable."],"exampleFix":"// before\nif (result['url']) {\n    return result['url'];\n} else {\n    throw new Error(`Can not find url: ${JSON.stringify(result)}`);\n}\n// after\nconst url = result['url'] ?? result?.data?.url;\nif (url) return url;\nif (result['code'] === 'NotFound.File') return null; // handle missing file\nthrow new Error(`getDownloadUrl: no url in response (HTTP ${res.status}): ${JSON.stringify(result)}`);","handlingStrategy":"type-guard","validationCode":"if (!file_id) throw new Error('file_id is required by getDownloadUrl');\nif (!drive_id) throw new Error('drive_id is required by getDownloadUrl');","typeGuard":"function isDownloadUrlResponse(data) {\n    return typeof data === 'object' && data !== null && typeof data.url === 'string' && data.url.length > 0;\n}","tryCatchPattern":"try {\n    const url = await getDownloadUrl(token, drive_id, fileId);\n} catch (e) {\n    if (e.message.startsWith('Can not find url')) {\n        // payload logged inside the error; verify drive_id/file_id pairing,\n        // check recycle bin, or re-fetch file_id before retrying\n    }\n    throw e;\n}","preventionTips":["Always obtain file_id and drive_id from the same API call / drive to avoid mismatched pairs.","Narrow the response with an isDownloadUrlResponse type guard and fail with a clear message otherwise.","Re-check the file still exists (not in recycle bin) before requesting a download URL.","Keep up with Alipan openAPI response schema changes."],"tags":["aliyun-drive","unexpected-response","api-schema","download-url","backup"],"backgroundTag":"unexpected-api-response","analyzedSha":"594d32ede96acd106b0256deaa8bb440ffcdff40","analyzedAt":"2026-09-02T18:12:21.811Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}