Skip to content

Improve error handling: surface silently swallowed errors - #27

Closed
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1782395712-improve-error-handling
Closed

Improve error handling: surface silently swallowed errors#27
devin-ai-integration[bot] wants to merge 1 commit into
mainfrom
devin/1782395712-improve-error-handling

Conversation

@devin-ai-integration

@devin-ai-integration devin-ai-integration Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Summary

Five places across src/ silently swallow errors via empty catch {} blocks or -ErrorAction SilentlyContinue. This PR adds Write-Warning (or Write-Verbose) so failures are visible to the user.

Note: the Get-RegistrySnapshot destructive-restore issue was already addressed in #28 (omitting unreadable entries from the backup). This PR covers the remaining silent-error sites.

Test-PolicyValueMatches (PlatformPolicy.ps1) — catch block now warns on type-conversion failures so -Doctor reports surface the reason instead of silently returning $false.

Remove-PolicyValue (PlatformPolicy.ps1) — the Registry branch replaced -ErrorAction SilentlyContinue on Remove-ItemProperty with try/catch -ErrorAction Stop + warning, so failed removal steps are visible.

Get-BraveProfilePreferenceFiles (ProfilePreferences.ps1) — replaced -ErrorAction SilentlyContinue on Get-ChildItem with try/catch -ErrorAction Stop + warning, so permission errors enumerating profile directories are visible.

Update-BackupProfileFiles (Backup.ps1) — split the early-return guard: falsy $BackupPath is still silent (expected with -NoBackup), but a non-null path that doesn't exist on disk now warns.

Get-FullFileSystemPath (Common.ps1) — added Write-Verbose for the PSPath fallback, traceable with -Verbose without cluttering normal output.

Link to Devin session: https://app.devin.ai/sessions/f10d795d09af4d2f9cb5eafede4ff49b
Requested by: @osfv

@osfv osfv self-assigned this Jun 25, 2026
@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment, CI, and merge conflict monitoring

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Greptile Summary

This PR converts six silent-failure sites across src/ to surface errors via Write-Warning or Write-Verbose, and splits a guard condition in Update-BackupProfileFiles so a non-null-but-missing backup path is explicitly warned about.

  • Remove-PolicyValue (PlatformPolicy.ps1): -ErrorAction SilentlyContinue on Remove-ItemProperty replaced with try/catch -ErrorAction Stop + Write-Warning; as flagged in a prior review thread, this emits spurious warnings when a registry property simply doesn't exist (a normal expected no-op).
  • Get-BraveProfilePreferenceFiles (ProfilePreferences.ps1): Get-ChildItem switched from -ErrorAction SilentlyContinue to -ErrorAction Stop inside a try/catch; this changes the behaviour from "enumerate what you can, skip errors" to "abort the entire enumeration on the first item-level error", potentially omitting later valid profile directories from processing.
  • Test-PolicyValueMatches, Get-FullFileSystemPath, and Update-BackupProfileFiles: lower-risk additions of Write-Warning/Write-Verbose with no behavioural regressions.

Confidence Score: 3/5

Two changes carry correctness concerns: the Remove-PolicyValue try/catch (surfaced in a prior thread) generates misleading warnings for the normal "property absent" no-op case, and the Get-ChildItem -ErrorAction Stop change in Get-BraveProfilePreferenceFiles can silently drop later valid profile directories from processing the moment any item-level error is encountered.

The Get-ChildItem -ErrorAction Stop change in profile enumeration is a behavioral regression from "skip errors and continue" to "abort on first error", which in an unusual filesystem configuration could cause Brave profile directories to be missed during debloat or restore. Combined with the pre-existing Remove-PolicyValue spurious-warning issue, both the registry undo path and the profile enumeration path have active concerns that warrant fixes before merge.

src/ProfilePreferences.ps1 (premature enumeration abort on Get-ChildItem -ErrorAction Stop) and src/PlatformPolicy.ps1 (Remove-PolicyValue warning on expected absent-property no-op) need attention before merge.

Important Files Changed

Filename Overview
src/Backup.ps1 Splits the early-return guard in Update-BackupProfileFiles so a non-null path that doesn't exist emits a warning; no logic change to Restore-RegistryBackup.
src/Common.ps1 Adds Write-Verbose to the PSPath-fallback catch block in Get-FullFileSystemPath; diagnostic-only, no logic change.
src/PlatformPolicy.ps1 Replaces -ErrorAction SilentlyContinue with try/catch -ErrorAction Stop + Write-Warning in Remove-PolicyValue (can emit spurious warnings when the property simply doesn't exist — already flagged), and adds Write-Warning to the Test-PolicyValueMatches catch block.
src/ProfilePreferences.ps1 Wraps `Get-ChildItem

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Get-BraveProfilePreferenceFiles] --> B{Root empty or missing?}
    B -- Yes --> C[Return empty array]
    B -- No --> D["try: Get-ChildItem -ErrorAction Stop"]
    D -- Success --> E[ForEach-Object: collect Preferences paths]
    E --> F[Return files array]
    D -- "First item error (new: Stop)" --> G[catch block fires]
    G --> H["Write-Warning: Failed to enumerate..."]
    H --> I[Return partial array — later profiles missed]

    J[Remove-PolicyValue Registry] --> K{Registry key path exists?}
    K -- No --> L[return]
    K -- Yes --> M["try: Remove-ItemProperty -ErrorAction Stop"]
    M -- Success --> L
    M -- "Property not found (normal no-op)" --> N[catch fires]
    N --> O["Write-Warning: Failed to remove... (spurious)"]
    O --> L
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[Get-BraveProfilePreferenceFiles] --> B{Root empty or missing?}
    B -- Yes --> C[Return empty array]
    B -- No --> D["try: Get-ChildItem -ErrorAction Stop"]
    D -- Success --> E[ForEach-Object: collect Preferences paths]
    E --> F[Return files array]
    D -- "First item error (new: Stop)" --> G[catch block fires]
    G --> H["Write-Warning: Failed to enumerate..."]
    H --> I[Return partial array — later profiles missed]

    J[Remove-PolicyValue Registry] --> K{Registry key path exists?}
    K -- No --> L[return]
    K -- Yes --> M["try: Remove-ItemProperty -ErrorAction Stop"]
    M -- Success --> L
    M -- "Property not found (normal no-op)" --> N[catch fires]
    N --> O["Write-Warning: Failed to remove... (spurious)"]
    O --> L
Loading

Fix All in Cursor Fix All in Codex

Reviews (2): Last reviewed commit: "Improve error handling: surface silently..." | Re-trigger Greptile

Comment thread src/PlatformPolicy.ps1
Comment on lines 259 to 267
if ($Target.Kind -eq 'Registry') {
if (Test-Path -LiteralPath $Target.Path) {
Remove-ItemProperty -LiteralPath $Target.Path -Name $Name -ErrorAction SilentlyContinue
try {
Remove-ItemProperty -LiteralPath $Target.Path -Name $Name -ErrorAction Stop
}
catch {
Write-Warning "Failed to remove registry value '$Name': $($_.Exception.Message)"
}
}

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 Spurious warnings when removing an already-absent registry value

The prior -ErrorAction SilentlyContinue was intentional: Remove-ItemProperty emits a non-terminating error when the named property simply does not exist, and that case is a normal, expected no-op (e.g., running restore a second time, or restoring a backup that was created before debloating was ever applied). Replacing it with try/catch -ErrorAction Stop now turns that no-op into a user-visible Write-Warning "Failed to remove registry value...", which is misleading in those legitimate scenarios. Consider guarding with a property-existence check before calling Remove-ItemProperty, or catching only on a specific exception type, to preserve the silent-skip behaviour for the "value not found" case while still surfacing genuine permission errors.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Cursor Fix in Codex

- Test-PolicyValueMatches: warn on type conversion failures so Doctor
  reports surface the mismatch reason
- Remove-PolicyValue: replace -ErrorAction SilentlyContinue with
  try/catch and warning when removing registry values fails
- Get-BraveProfilePreferenceFiles: replace -ErrorAction SilentlyContinue
  with try/catch and warning when profile directory enumeration fails
- Update-BackupProfileFiles: warn when backup file is unexpectedly
  missing instead of silently skipping profile metadata updates
- Get-FullFileSystemPath: add Write-Verbose when PSPath resolution falls
  back to direct resolution

Co-Authored-By: adasdasd dasdasdas <fearlemail@gmail.com>
@osfv

osfv commented Jun 25, 2026

Copy link
Copy Markdown
Owner

@greptileai safe 2 merge?

@devin-ai-integration

Copy link
Copy Markdown
Contributor Author

Superseded by #29.

Greptile's "3/5" was right: this PR's core fix targets Get-RegistrySnapshot, which has no callers — the live backup path is New-Backup → Get-PolicySnapshot → Get-PolicyValue, so the readError guard never fired at runtime. The Remove-PolicyValue change (-ErrorAction Stop) also introduced spurious "failed to remove" warnings on idempotent removes.

#29 implements the same unreadable-value protection in the live path (Get-PolicyValueGet-PolicySnapshotRestore-RegistryBackup skips readError entries), removes the dead Get-RegistrySnapshot, and leaves Remove-PolicyValue idempotent. CI green (5/5).

Comment on lines +68 to +79
try {
Get-ChildItem -LiteralPath $Root -Directory -ErrorAction Stop |
ForEach-Object {
$preferencesPath = Join-Path $_.FullName 'Preferences'
if (Test-Path -LiteralPath $preferencesPath) {
[void]$files.Add($preferencesPath)
}
}
}
}
catch {
Write-Warning "Failed to enumerate profile directories under '$Root': $($_.Exception.Message)"
}

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 -ErrorAction Stop can truncate the profile list on a partial error

Get-ChildItem with -ErrorAction Stop converts each item-level non-terminating error into a terminating exception, so the first inaccessible profile subdirectory aborts the entire enumeration. Profiles that appear later in directory order are never added to $files and silently go unprocessed — they won't get debloated or restored. The original -ErrorAction SilentlyContinue intentionally continued past individual errors to collect as many profiles as possible.

Consider switching to -ErrorAction SilentlyContinue on Get-ChildItem and separately detecting whether any errors were generated (e.g., via -ErrorVariable evChildItem), then issuing the warning only if $evChildItem.Count -gt 0. This preserves the "collect as much as possible" behaviour while still surfacing that something went wrong.

Fix in Cursor Fix in Codex

@greptile-apps

greptile-apps Bot commented Jun 25, 2026

Copy link
Copy Markdown

Yes, this is safe to merge. The changes are minimal and surgical — each one replaces a silent failure with a visible warning or verbose message without altering any logic or control flow. Specifically:

  • Backup.ps1: The split guard preserves identical behavior for both the -NoBackup (falsy path) and missing-path cases; it just surfaces a warning for the latter.
  • Common.ps1: Write-Verbose in the catch block is noise-free at normal verbosity; the fallback logic is unchanged.
  • PlatformPolicy.ps1 (Remove-PolicyValue): try/catch with -ErrorAction Stop is the correct pattern for surfacing registry errors. The return after the registry block is still intact.
  • PlatformPolicy.ps1 (Test-PolicyValueMatches): Warning is added before the existing return $false — no behavior change, just visibility.
  • ProfilePreferences.ps1: Wrapping Get-ChildItem in try/catch is idiomatic PowerShell 5.1 and preserves the existing return $files.ToArray() path.

No dry-run/WhatIf behavior, backup/restore logic, or policy manifest references are touched. All patterns are Windows PowerShell 5.1 compatible. Good to go.

@osfv osfv closed this Jun 25, 2026
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