Skip to content

fix: continue walk on per-file errors instead of log.Fatal#56

Open
leno23 wants to merge 1 commit into
dolph:mainfrom
leno23:fix/nonfatal-walk-errors-issue-6
Open

fix: continue walk on per-file errors instead of log.Fatal#56
leno23 wants to merge 1 commit into
dolph:mainfrom
leno23:fix/nonfatal-walk-errors-issue-6

Conversation

@leno23
Copy link
Copy Markdown

@leno23 leno23 commented May 17, 2026

Summary

  • Add noteError / hadErrors and exit non-zero from main when any file-level error occurred.
  • Log and continue when a directory cannot be read, or when stat/open/read/write/rename fails.
  • Fix goroutine loop variable capture when spawning per-entry workers.

NewFile path resolution failures remain fatal (startup-level).

Test plan

  • go test ./...
  • TestWalkDirContinuesOnUnreadableDirectory

Partial fix for #6

Made with Cursor

Record errors from unreadable directories, failed stats/opens/reads,
writes, and renames; exit non-zero from main when any occurred.
Pass goroutine-safe child paths into worker goroutines.

Partial fix for dolph#6 (root NewFile/abs failures still fatal).

Co-authored-by: Cursor <cursoragent@cursor.com>
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fef7960386

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +29 to +30
if !fr.hadErrors.Load() {
t.Fatal("expected hadErrors after unreadable directory")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Skip unreadable-dir assertion when running as root

This test hard-codes the expectation that chmod 000 makes private unreadable, but that is false when tests run as uid 0 (a common CI/container setup), where os.ReadDir can still succeed and hadErrors stays false. In those environments the test fails even though traversal logic is fine, so it introduces a deterministic false negative. Gate this assertion behind a non-root check (or otherwise detect whether the directory is actually unreadable before asserting).

Useful? React with 👍 / 👎.

Comment thread file_handling.go
Comment on lines 97 to 99
if err := os.Rename(tempName, f.Path); err != nil {
log.Fatalf("Unable to atomically move temp file %v to %v: %v", tempName, f.Path, err)
f.logError("Unable to atomically move temp file %v to %v: %v", tempName, f.Path, err)
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clean up temp file after failed atomic rename

After this change, write failures are non-fatal and execution continues, but Write leaves tempName behind when os.Rename(tempName, f.Path) fails. In real error cases (e.g., transient rename failures), this now accumulates random temp files across many files instead of aborting once, polluting the target tree and affecting later runs. Add cleanup of tempName on the rename-error path.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant