Log shipping - Let helper failures reach the caller instead of escaping it - #10644
Log shipping - Let helper failures reach the caller instead of escaping it#10644andreasjordan wants to merge 3 commits into
Conversation
…ng it The four New-DbaLogShipping* helper functions carried fourteen Stop-Function -Continue calls without any enclosing loop, and Invoke-DbaDbLogShipping one more. When a helper failed without EnableException, the continue unwound out of the helper, BYPASSED the try/catch that Invoke-DbaDbLogShipping wraps around every helper call, and consumed an iteration of its per-database loop: the database vanished from the run without $setupResult ever being set to Failed, the secondary phases were skipped silently, and no status was emitted. Two changes, one mechanism: the helpers now stop and return (their failures warn, or throw under EnableException), and Invoke-DbaDbLogShipping passes EnableException = $true into all four helper splats so a failure throws into the catch that was always meant to receive it - $setupResult becomes Failed and the later phases are skipped as designed. The command's own empty-database guard also stops and returns now. Part of the #10638 inventory, batched as one PR because the fifteen sites share this single mechanism. The test file gains its first integration test (and with it its first instance reference, moving it into the HADR lane - until now it ran in no scenario-scoped lane at all, see #10629): the loop-counter pattern over an empty -Database, red on the unfixed code with "Expected 3, but got 0". References #10638 (do *LogShipping*) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The new loop-counter test used $TestConfig.Temp as SharedPath, which is a UNC share in the lab but a local path on CI, so CI tripped the UNC form check before ever reaching the database guard the test is about. The loop assertion held either way - only the warning text differed. The share now only has to look like a UNC path: a dbatoolsci dummy passes the form check, IgnoreFileChecks skips the reachability test, and the run reaches the database guard in every environment. Verified on PS 5.1, the edition the HADR lane runs. References #10638 (do Invoke-DbaDbLogShipping) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
potatoqualitee
left a comment
There was a problem hiding this comment.
The new EnableException = $true propagation correctly routes helper failures into the caller's catches, but those catches still call Stop-Function ... -Continue (public/Invoke-DbaDbLogShipping.ps1, primary catch around line 1938 and secondary catch around line 2071). Both are inside the per-database foreach, so -Continue advances that loop before the status object around line 2079 is emitted. A helper failure therefore still produces no Result = "Failed" object, contrary to this PR's central behavior claim. Please remove the catch-level -Continue so $setupResult can suppress later phases and reach the result object, and add a regression test that drives a helper failure through the catch and asserts the failed status object is returned.
… fails Review follow-up: the catches around the helper calls ran Stop-Function -Continue, which advanced the per-database loop past the status object at the end of the iteration - a helper failure returned nothing at all. The -Continue is gone at both catch sites; $setupResult already suppresses the later phases, so the Failed object with its comment now reaches the caller. The new regression test drives a real setup (database, full backup, restored secondary) into the primary catch via a mocked helper and asserts the Failed status object - red on the old code, green on the fix via the lab harness. (do Invoke-DbaDbLogShipping) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Fixed in 76948da - the review is right, and the catch-level The change: both catch sites (primary region and secondary region) drop The regression test runs the real path on the HADR instance - create the database, take the full backup, let the command restore the secondary - and mocks only Two adjacent defects documented while working this, deliberately not changed here:
created by Claude and reviewed by Andreas Jordan |
potatoqualitee
left a comment
There was a problem hiding this comment.
The updated head resolves the prior blocking feedback; no material issues remain.
Summary
Seventh fix from the #10638 inventory, batched as one PR because fifteen sites share a single mechanism: the four
New-DbaLogShipping*helper functions carried fourteenStop-Function -Continuecalls without any enclosing loop, plus one inInvoke-DbaDbLogShippingitself.The compound failure mode: when a helper failed without
EnableException, thecontinueunwound out of the helper, bypassed the try/catch thatInvoke-DbaDbLogShippingwraps around every helper call (flow control is not an exception), and consumed an iteration of its per-database loop. The database vanished from the run -$setupResultnever becameFailed, the secondary phases were skipped silently, and no status object was emitted.Fix
Two changes, one mechanism:
returnat all fourteen sites - they warn, or throw underEnableException.Invoke-DbaDbLogShippingpassesEnableException = $trueinto all four helper splats, so a helper failure throws into the catch that was always meant to receive it:$setupResult = "Failed", later phases skipped as designed, proper status emitted. Its own empty-database guard also stops and returns now.Tests
The test file gains its first integration test - and with it its first instance reference, moving it into the HADR lane; until now it ran in no scenario-scoped lane at all (see #10629). The loop-counter pattern over an empty
-Database: red on the unfixed code ("Expected 3, but got 0"), green on the fix, verified via the lab harness against SQL04\SQL2025.References #10638
created by Claude and reviewed by Andreas Jordan
🤖 Generated with Claude Code