{"record":{"id":"c06e65bc4bd1da46","repo":"koodo-reader/koodo-reader","slug":"failed-to-create-directory-part","errorCode":null,"errorMessage":"Failed to create directory: ${part}","messagePattern":"Failed to create directory: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/utils/file/localFile.ts","lineNumber":312,"sourceCode":"    const pathParts = normalizedPath\n      .split(\"/\")\n      .filter((part) => part.length > 0);\n\n    let currentHandle = baseHandle;\n\n    for (const part of pathParts) {\n      try {\n        // 尝试获取现有文件夹\n        currentHandle = await currentHandle.getDirectoryHandle(part);\n      } catch (error) {\n        // 如果文件夹不存在，创建新文件夹\n        try {\n          currentHandle = await currentHandle.getDirectoryHandle(part, {\n            create: true,\n          });\n        } catch (createError) {\n          console.error(`Error creating directory ${part}:`, createError);\n          throw new Error(`Failed to create directory: ${part}`);\n        }\n      }\n    }\n\n    return currentHandle;\n  }\n\n  // 保存文件到本地目录（支持指定文件夹）\n  static async saveFile(\n    filename: string,\n    content: string | ArrayBuffer,\n    folderPath?: string\n  ): Promise<boolean> {\n    try {\n      const directoryHandle = await this.getStoredDirectoryHandle();\n      if (!directoryHandle) {\n        throw new Error(\"No directory access permission\");\n      }","sourceCodeStart":294,"sourceCodeEnd":330,"githubUrl":"https://github.com/koodo-reader/koodo-reader/blob/7d40df41e05cfc0a341fe9ea66a12819b522b7fa/src/utils/file/localFile.ts#L294-L330","documentation":"ensureDirectoryExists() walks each path segment of folderPath, calling getDirectoryHandle(part, {create:true}) on the current handle. If any segment cannot be created or opened, it logs the underlying error and rethrows this sanitized 'Failed to create directory: <part>' error naming the offending segment. Common underlying causes are invalid characters in the segment name, name collisions with an existing file, or OS-level permission failures.","triggerScenarios":"Calling saveFile(content, fileName, folderPath) where folderPath contains a segment with filesystem-illegal characters (e.g. ':' or '\\\\' on Windows, '/' mid-segment), a segment name matching an existing FILE in the parent directory, an empty segment from a malformed path like 'a//b', or a name too long for the OS.","commonSituations":"Folder paths derived from book titles/authors containing reserved characters, nested paths built by string concatenation with accidental double slashes, or saving into a synced/locked directory (OneDrive, network share) that rejects creation.","solutions":["Sanitize folderPath segments before calling saveFile: strip reserved characters (<>:\"/\\\\|?*), trim, and collapse empty segments","Split the path yourself and create directories one level at a time to identify the failing segment","Check the console.error line above the throw — it logs the original createError with the real OS reason","Ensure the segment does not collide with an existing file of the same name in the parent directory"],"exampleFix":"// before\nawait LocalFileService.saveFile(content, fileName, `books/${book.title}/covers`);\n// after\nconst safeTitle = book.title.replace(/[<>:\"/\\\\|?*]/g, \"_\").trim();\nconst folderPath = [\"books\", safeTitle, \"covers\"].filter(Boolean).join(\"/\");\nawait LocalFileService.saveFile(content, fileName, folderPath);","handlingStrategy":"validation","validationCode":"function sanitizeFolderPath(p: string): string {\n  return p\n    .split(\"/\")\n    .map((seg) => seg.replace(/[<>:\"\\\\|?*\\x00-\\x1f]/g, \"_\").trim())\n    .filter(Boolean)\n    .join(\"/\");\n}\n// usage: saveFile(content, name, sanitizeFolderPath(rawPath))","typeGuard":"function isSafeSegment(seg: string): boolean {\n  return seg.length > 0 && seg.length < 255 && !/[<>:\"\\\\|?*\\/\\x00-\\x1f]/.test(seg);\n}","tryCatchPattern":"try {\n  await LocalFileService.saveFile(content, name, path);\n} catch (e) {\n  if (e.message.startsWith(\"Failed to create directory:\")) {\n    const badPart = e.message.split(\":\")[1]?.trim();\n    console.warn(\"sanitize and retry for segment:\", badPart);\n  } else throw e;\n}","preventionTips":["Sanitize every path segment (reserved chars, length) before saveFile","Filter out empty segments caused by double slashes","Avoid deriving folder names raw from book titles/authors","Check the console.error log above the throw for the real OS-level cause (e.g. name collision with an existing file)"],"tags":["filesystem","directories","validation"],"backgroundTag":"directory-creation-failed","analyzedSha":"7d40df41e05cfc0a341fe9ea66a12819b522b7fa","analyzedAt":"2026-08-29T01:41:43.691Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}