Skip to content

fix(core): use enumeratorAtPath for iOS shallow entity enumeration#11182

Open
NathanWalker wants to merge 5 commits intomainfrom
fix/ios-filesystem-robustness
Open

fix(core): use enumeratorAtPath for iOS shallow entity enumeration#11182
NathanWalker wants to merge 5 commits intomainfrom
fix/ios-filesystem-robustness

Conversation

@NathanWalker
Copy link
Copy Markdown
Contributor

Summary

Core's iOS FileSystemAccess.enumEntities() implementation was brittle - this fixes a startup crash observed in some app setups during font registration.

Problem

In iOS, enumEntities() used NSFileManager.contentsOfDirectoryAtPathError(path) and then immediately accessed files.count.

In the failing startup path, that call could return undefined, which caused:

  • TypeError: Cannot read properties of undefined (reading 'count')
  • crash during registerFontsInFolder()

Fix

  • Replace contentsOfDirectoryAtPathError(path) with enumeratorAtPath(path) in the iOS file-system access layer.
  • Preserve the existing shallow enumeration contract by only surfacing direct children.
  • Call skipDescendants() for child directories so nested contents are not enumerated.
  • Add a regression test to verify eachEntity() does not enumerate nested files.

enumeratorAtPath(path) avoids the more brittle ...Error bridge path while still giving us the directory contents we need. The implementation keeps eachEntity() behavior aligned with the previous shallow directory listing semantics.

@NathanWalker NathanWalker requested a review from CatchABus April 16, 2026 19:36
@nx-cloud
Copy link
Copy Markdown

nx-cloud bot commented Apr 16, 2026

View your CI Pipeline Execution ↗ for commit 9880fa4

Command Status Duration Result
nx test apps-automated -c=android ✅ Succeeded 3m 49s View ↗
nx run-many --target=test --configuration=ci --... ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-04-17 03:45:34 UTC

@NathanWalker NathanWalker requested a review from Copilot April 16, 2026 21:35
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes a brittle iOS implementation of FileSystemAccess.enumEntities() that could crash at startup (e.g., during font registration) by switching from contentsOfDirectoryAtPathError() to enumeratorAtPath() while preserving shallow enumeration behavior.

Changes:

  • Reworked iOS entity enumeration to use NSFileManager.enumeratorAtPath() and skip descendant enumeration.
  • Updated eachEntity() behavior to remain shallow by skipping directory descendants.
  • Added a regression test intended to ensure nested files are not enumerated.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
packages/core/file-system/file-system-access.ios.ts Switches iOS enumeration to enumeratorAtPath() and skips descendants to maintain shallow semantics.
apps/automated/src/file-system/file-system-tests.ts Adds a regression assertion intended to ensure eachEntity() doesn’t enumerate nested files.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/automated/src/file-system/file-system-tests.ts
Comment on lines 632 to 636
const enumerator = fileManager.enumeratorAtPath(path);
if (!enumerator) {
if (onError) {
onError(new Error("Failed to enum files for folder '" + path + "': " + ex));
onError(new Error("Failed to enum files for folder '" + path + "'"));
}
Copy link

Copilot AI Apr 16, 2026

Choose a reason for hiding this comment

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

onError now reports a generic "Failed to enum files…" message when enumeratorAtPath returns null, losing the underlying reason (e.g., non-existent path, permission error) that previously came from the thrown exception. It would be more actionable to either (1) check folderExists(path) up front and report a specific "no folder exists" error, or (2) include additional context (when available) about why enumeration failed.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Implemented in 827cf2a. enumEntities() now checks folderExists(path) first and reports a specific missing-folder error, and the enumeratorAtPath null case now returns a more actionable message (unable to create directory enumerator).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We likely don't want to return in this case, just print the error but allow it to proceed because this can be an innocent condition but having it in the logs will be helpful in case.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

We likely don't want to return in this case, just print the error but allow it to proceed because this can be an innocent condition but having it in the logs will be helpful in case.

@copilot adjust given this case.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Adjusted in 9880fa4. For the benign iOS enumEntities cases, we now log diagnostics with console.error and return without invoking onError, so startup can continue while still leaving a trace in logs.

Copy link
Copy Markdown

Copilot AI commented Apr 16, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cloud.nx.app
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node ./bin/post-install (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/NativeScript/NativeScript/node_modules/.bin/nx run core:lint (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/NativeScript/NativeScript/node_modules/.bin/nx run core:test (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copy link
Copy Markdown

Copilot AI commented Apr 16, 2026

Just as a heads up, I was blocked by some firewall rules while working on your feedback. Expand below for details.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • cloud.nx.app
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node ./bin/post-install (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/NativeScript/NativeScript/node_modules/.bin/nx run core:build (dns block)
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/NativeScript/NativeScript/node_modules/.bin/nx run core:lint (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

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.

3 participants