{"record":{"id":"da36e80a1522bd28","repo":"koodo-reader/koodo-reader","slug":"failed-to-get-folder-info-response-statustext","errorCode":null,"errorMessage":"Failed to get folder info: ${response.statusText}","messagePattern":"Failed to get folder info: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/utils/file/googlePicker.ts","lineNumber":135,"sourceCode":"      throw new Error(`Failed to get file metadata: ${response.statusText}`);\n    }\n\n    return await response.json();\n  }\n\n  // 获取文件夹信息\n  async getFolderInfo(folderId: string): Promise<any> {\n    const response = await fetch(\n      `https://www.googleapis.com/drive/v3/files/${folderId}?fields=id,name,mimeType`,\n      {\n        headers: {\n          Authorization: `Bearer ${this.accessToken}`,\n        },\n      }\n    );\n\n    if (!response.ok) {\n      throw new Error(`Failed to get folder info: ${response.statusText}`);\n    }\n\n    return await response.json();\n  }\n}\n","sourceCodeStart":117,"sourceCodeEnd":141,"githubUrl":"https://github.com/koodo-reader/koodo-reader/blob/7d40df41e05cfc0a341fe9ea66a12819b522b7fa/src/utils/file/googlePicker.ts#L117-L141","documentation":"GoogleDriveService.getFolderInfo() queries Drive (files list filtered by folder name/mimeType) to locate or describe a folder, and throws this error on any non-ok response. Like the other Drive methods, failures are usually auth-, permission-, or rate-limit-related rather than logic errors.","triggerScenarios":"Calling getFolderInfo with an expired access token, when the authenticated account cannot see the folder (shared drive not in scope), malformed query parameters rejected with 400, or 429/5xx from Drive under rate limiting.","commonSituations":"First-time sync before scopes are granted, user switched Google accounts so the token belongs to an account without the folder, or bulk operations tripping Drive per-minute query quotas.","solutions":["On 401/403, refresh the token or re-run OAuth with the correct scopes (drive metadata access) and retry","Validate the query string (name/mimeType filters) — 400 indicates a malformed query","Retry 429/5xx with exponential backoff and jitter","Confirm the folder exists under the currently authenticated account before querying"],"exampleFix":"// before\nif (!response.ok) {\n  throw new Error(`Failed to get folder info: ${response.statusText}`);\n}\n// after\nif (!response.ok) {\n  if (response.status === 401) {\n    await this.refreshAccessToken();\n    return this.getFolderInfo(folderName);\n  }\n  if (response.status === 429) {\n    await new Promise((r) => setTimeout(r, 2000));\n    return this.getFolderInfo(folderName);\n  }\n  throw new Error(`Failed to get folder info: HTTP ${response.status}`);\n}","handlingStrategy":"retry","validationCode":"if (!drive.accessToken) throw new Error(\"not authenticated\");\nif (!folderName || folderName.includes(\"'\")) throw new Error(\"invalid folder name\");","typeGuard":"function isDriveFolder(v: unknown): v is { id: string; name: string; mimeType: string } {\n  return !!v && typeof v === \"object\" && (v as any).mimeType === \"application/vnd.google-apps.folder\";\n}","tryCatchPattern":"try {\n  const info = await drive.getFolderInfo(name);\n} catch (e) {\n  if (e.message.includes(\"Failed to get folder info\")) {\n    await sleep(2000);\n    return drive.getFolderInfo(name); // backoff retry\n  } else throw e;\n}","preventionTips":["Escape single quotes in Drive query strings to avoid 400s","Refresh tokens on 401 before surfacing errors","Throttle folder lookups to respect Drive per-minute quotas","Verify the active Google account owns/see the folder"],"tags":["network","google-drive","oauth","http"],"backgroundTag":"google-drive-api-error","analyzedSha":"7d40df41e05cfc0a341fe9ea66a12819b522b7fa","analyzedAt":"2026-08-29T01:41:43.691Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}