fix(opencode): improve removeEmptyParents error handling and loop clarity
- Distinguish recoverable errors (ENOTEMPTY, ENOENT) from fatal errors in removeEmptyParents() catch block — skip level and continue upward on TOCTOU races or concurrent removal, break only on fatal errors (EACCES) - Add comment clarifying loop invariant for missing-path continue branch Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
02b18828be
commit
a00526fe8d
|
|
@ -557,14 +557,21 @@ LOAD and execute from: {project-root}/{{bmadFolderName}}/{{path}}
|
|||
if (!fullPath.startsWith(resolvedProject + path.sep) && fullPath !== resolvedProject) break;
|
||||
try {
|
||||
if (!(await fs.pathExists(fullPath))) {
|
||||
// Dir already gone — advance current; last is reset at top of next iteration
|
||||
current = path.dirname(current);
|
||||
continue;
|
||||
}
|
||||
const remaining = await fs.readdir(fullPath);
|
||||
if (remaining.length > 0) break;
|
||||
await fs.rmdir(fullPath);
|
||||
} catch {
|
||||
break;
|
||||
} catch (error) {
|
||||
// ENOTEMPTY: TOCTOU race (file added between readdir and rmdir) — skip level, continue upward
|
||||
// ENOENT: dir removed by another process between pathExists and rmdir — skip level, continue upward
|
||||
if (error.code === 'ENOTEMPTY' || error.code === 'ENOENT') {
|
||||
current = path.dirname(current);
|
||||
continue;
|
||||
}
|
||||
break; // fatal error (e.g. EACCES) — stop upward walk
|
||||
}
|
||||
current = path.dirname(current);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue