{"record":{"id":"4ca9b307817e0bc8","repo":"huiyadanli/RevokeMsgPatcher","slug":"sourcedirname","errorCode":null,"errorMessage":"源目录不存在: {sourceDirName}","messagePattern":"源目录不存在: (.+?)","errorType":"exception","errorClass":"DirectoryNotFoundException","httpStatus":null,"severity":"error","filePath":"RevokeMsgPatcher/Model/LiteLoaderRowData.cs","lineNumber":307,"sourceCode":"                    Directory.CreateDirectory(localDirectory); // 确保目录存在\n                    File.WriteAllBytes(localPath, data);\n                    return localPath;\n                }\n                else\n                {\n                    throw new Exception(\"下载失败\");\n                }\n            }\n        }\n\n        private void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs = true)\n        {\n            DirectoryInfo dir = new DirectoryInfo(sourceDirName);\n            DirectoryInfo[] dirs = dir.GetDirectories();\n\n            if (!dir.Exists)\n            {\n                throw new DirectoryNotFoundException(\"源目录不存在: \" + sourceDirName);\n            }\n\n            if (!Directory.Exists(destDirName))\n            {\n                Directory.CreateDirectory(destDirName);\n            }\n\n            FileInfo[] files = dir.GetFiles();\n            foreach (FileInfo file in files)\n            {\n                string tempPath = Path.Combine(destDirName, file.Name);\n                file.CopyTo(tempPath, true);\n            }\n\n            if (copySubDirs)\n            {\n                foreach (DirectoryInfo subdir in dirs)\n                {","sourceCodeStart":289,"sourceCodeEnd":325,"githubUrl":"https://github.com/huiyadanli/RevokeMsgPatcher/blob/89cbbb3f0cc896d5d092de0199a635c5c39944b6/RevokeMsgPatcher/Model/LiteLoaderRowData.cs#L289-L325","documentation":"DirectoryCopy throws DirectoryNotFoundException when the source directory does not exist. It is called after zip extraction with pluginPath = FindDirectoryWithJson(extractPath); if that returned null (no package.json/manifest.json found within depth 2), copying from a null/non-existent path throws.","triggerScenarios":"The downloaded zip extracted without a package.json/manifest.json at depth <= 2, so FindDirectoryWithJson returned null and DirectoryCopy(null,...) failed; or the zip layout changed / download was truncated.","commonSituations":"Plugin repo changed its archive structure; a corrupted or partial download produced an unexpected directory tree.","solutions":["Re-download the package (click Update again) in case of a truncated archive.","If it persists, the plugin's zip layout changed; report it or raise FindDirectoryWithJson's maxDepth / add the new manifest filename."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"string pluginPath = FindDirectoryWithJson(extractPath);\nif (pluginPath == null || !Directory.Exists(pluginPath))\n{\n    UpdateStatus(\"解压后未找到插件目录，请重新下载。\");\n    Directory.Delete(extractPath, true);\n    return;\n}","typeGuard":null,"tryCatchPattern":"try\n{\n    DirectoryCopy(pluginPath, LocalPath);\n}\ncatch (DirectoryNotFoundException)\n{\n    UpdateStatus(\"源目录不存在，请重新下载并重试。\");\n}","preventionTips":["Validate FindDirectoryWithJson's result before copying.","Re-download on a null plugin path rather than letting DirectoryCopy throw.","If a plugin repo changes its archive layout, update FindDirectoryWithJson depth/filenames."],"tags":["download","filesystem","liteloaderqqnt"],"backgroundTag":null,"analyzedSha":"89cbbb3f0cc896d5d092de0199a635c5c39944b6","analyzedAt":"2026-08-13T10:37:37.073Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}