Fix incomplete directory cleanup on scaffolding failure - #122
Conversation
svlandeg
left a comment
There was a problem hiding this comment.
Thanks for the PR!
This leaves behind an incomplete and broken directory on the user's disk. If the user resolves the external issue and tries to run the command again, it fails
immediately because fastapi-new explicitly blocks scaffolding if the directory already exists, forcing the user to manually delete the broken directory.
In my honest opinion, it really isn't that big a deal to "manually" delete the "broken" directory in the odd case that this happens. I'm not sure this edge case justifies the additional complexity to the code.
|
Thanks for the feedback! That makes sense — I agree that automatic recursive cleanup may add more complexity than this edge case warrants. My main concern was that after a failed dependency installation, the user has to manually delete the generated files. Would a smaller change be preferable where, on failure, the CLI simply reports that the project directory may be incomplete and prints its path with an instruction to remove it before retrying? That would improve the failure experience without automatically deleting anything. I’m happy to revise the PR that way, or close it if you feel the current behavior is sufficient. |
Description
Currently, when a user runs fastapi-new , the CLI executes several sequential steps (initializing with uv init --bare, adding dependencies, and writing
templates). If any of the steps after the initial directory creation fail—such as a network error during uv add fastapi[standard] or a permission issue when writing
templates—the CLI immediately exits.
This leaves behind an incomplete and broken directory on the user's disk. If the user resolves the external issue and tries to run the command again, it fails
immediately because fastapi-new explicitly blocks scaffolding if the directory already exists, forcing the user to manually delete the broken directory.
This PR introduces an atomic cleanup mechanism. If an error occurs during the scaffolding process for a newly created directory, the directory is safely removed before
raising the exit code, returning the user's system to a clean state.
Details of Changes
• Wrapped the core scaffolding execution (_setup, _install_dependencies, _write_template_files) in a try...except typer.Exit block inside the new command handler.
• Added logic to check if a new directory was successfully created by _setup.
• Used shutil.rmtree(config.path, ignore_errors=True) to clean up the orphaned directory.
• Added a rich toolkit warning ([yellow]Cleaned up incomplete directory[/yellow]) to notify the user of the automatic cleanup.
• Removed an inner import shutil block that could cause an UnboundLocalError.
Testing / Verification
[✓] Evaluated locally by forcefully failing _install_dependencies and verifying that the directory was successfully removed.
[✓] Ran the full test suite (uv run pytest tests); all 32 tests successfully passed without regressions.
[✓] Verified that the cleanup logic explicitly ignores the current working directory (if not current_dir), preventing accidental deletions when scaffolding in an
existing root folder.
Checklist
[✓] I have read the contributing guidelines.
[✓] My code follows the code style of this project.
[✓] I have run the test suite and all tests pass locally.
[✓] My changes do not introduce any new warnings or errors.
──────