Skip to content

Problem with Publish-AdfV2FromJson not yet failing even using errorActionPreference: stop#490

Open
NowinskiK wants to merge 1 commit into
developfrom
issue-472
Open

Problem with Publish-AdfV2FromJson not yet failing even using errorActionPreference: stop#490
NowinskiK wants to merge 1 commit into
developfrom
issue-472

Conversation

@NowinskiK
Copy link
Copy Markdown
Member

@NowinskiK NowinskiK commented May 27, 2026

Fixed

Problem

Publish-AdfV2FromJson was silently continuing after errors and always printing "Azure Data Factory files have been deployed successfully." even when:

  1. A config stage file contained an invalid property path (error ADFT0010), and
  2. An ADF object deployment failed at runtime (e.g. blocked by Azure Policy: RequestDisallowedByPolicy).

Setting $ErrorActionPreference = 'Stop' in the calling script had no effect because module functions execute in the module scope, which does not inherit preference variables from the caller's script scope.

Two compounding root causes:

  • Write-Error is non-terminating — errors were written to the error stream but execution continued normally, so the calling script had no way to detect the failure.
  • ForEach-Object pipeline absorbs terminating errors in PowerShell 5.1 — even genuinely terminating errors thrown by Azure cmdlets (e.g. New-AzResource blocked by policy) were swallowed by the pipeline and did not propagate to the caller.

Changes

New test file — test/Publish-AdfV2FromJson-ErrorHandling.Tests.ps1

Four unit tests that reproduce the bug and verify the fix, requiring no live Azure connection:

Test Purpose
Should throw with wrong config path (-DryRun) Reproduces ADFT0010 not terminating Publish-AdfV2FromJson
Should NOT throw when FailsWhenPathNotFound = $false Negative test — warning-only mode must still work
Should throw when deployment fails (Should -Throw) Reproduces Azure cmdlet terminating error being swallowed by ForEach-Object
Should throw without Pester's Should -Throw (explicit try/catch) Confirms the fix works independently of caller's $ErrorActionPreference

All four tests were red before the fix and are green after.

private/Update-PropertiesFromFile.ps1

  • Write-Error "ADFT0007: ..."throw — object not found in config (when FailsWhenConfigItemNotFound = $true)
  • Write-Error -Exception $excthrow $exc — invalid property path ADFT0010 (when FailsWhenPathNotFound = $true)

private/Deploy-AdfObject.ps1

  • Write-Error "ADFT0005: ..."throw — referenced dependency object not found (when IgnoreLackOfReferencedObject = $false)

private/Deploy-AdfObjectOnly.ps1

  • Write-Error "ADFT0012: ..."throw — unsupported Integration Runtime type
  • Write-Error "ADFT0013: ..."throw — unsupported ADF object type

public/Publish-AdfV2FromJson.ps1

  • Deployment loop: $adf.AllObjects() | ForEach-Object { Deploy-AdfObject -obj $_ }foreach ($obj in $adf.AllObjects()) { Deploy-AdfObject -obj $obj }
  • Deletion loop: same change for Remove-AdfObjectIfNotInSource

The foreach statement propagates terminating errors from Azure cmdlets correctly in all PowerShell versions; ForEach-Object (a pipeline cmdlet) was absorbing them in PowerShell 5.1.

changelog.md

New entry added under ## Unreleased.


Why throw and not $PSCmdlet.ThrowTerminatingError()

throw produces an exception that propagates through every layer of the call stack — including ForEach-Object pipelines and across module scope boundaries — regardless of $ErrorActionPreference. Write-Error only becomes terminating if $ErrorActionPreference = 'Stop' is set in the module's own scope, which the caller cannot control. Using throw at the error source removes this dependency entirely.

@NowinskiK NowinskiK changed the title Initial fix #472 Problem with Publish-AdfV2FromJson not yet failing even using errorActionPreference: stop May 27, 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.

Publish-AdfV2FromJson not yet failing even using errorActionPreference: stop

1 participant