Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add '-Reset' switch parameter to Test-PSFFunctionInterrupt (or add additional function) #606

Open
Callidus2000 opened this issue Dec 13, 2023 · 5 comments

Comments

@Callidus2000
Copy link

While using the FlowControl functions I often stumble over the following problem: I'm using Invoke-PSFProtectedCommand to often 😄

simple dummy code:

function Start-Check{
        Invoke-PSFProtectedCommand -Action "Perform Check which fails" -ScriptBlock {
            throw "Check failed" 
        } -Level host -RetryCount 2
        if (Test-PSFFunctionInterrupt) {
            Invoke-PSFProtectedCommand -Action "Perform remediation" -ScriptBlock {
                Write-PSFMessage "Fixed"
            } -Level host -RetryCount 2
            if (Test-PSFFunctionInterrupt) {
                Stop-PSFFunction -Level Error -Message "Problem could not be fixed" -EnableException $true -Tag $Name
            }
        }
}

Scenario is that

  • the first PSFProtectedCommand performs some backend checks (like 'is the server alive?') which uses throw to trigger the retry count
  • The first Test-PSFFunctionInterrupt registers that the checks have failed and
  • uses the second PSFProtecedCommand to fix the problem (like restarting the service)

Problem is that the second Test-PSFFunctionInterrupt returns $true and the complete function stops. It would be great if you could provide a function/parameter to clean the $psframework_killqueue.

@FriedrichWeinmann
Copy link
Member

You are totally right, that for this kind of flow we need a reset capability.
While some of it could be handled by the -ErrorEvent parameter, there are clear cases where this is not enough.
Added to the backlog for the next release.

@Callidus2000
Copy link
Author

Mentioning the -ErrorEvent parameter:
Is there a way to access the error which is causing the ProtectedCommand to fail silently?
I assume from the parameter names like ErrorVariable and ErrorEvent that you've got prepared something for this. But those params (like others) are not included in the detailed command help and I've not yet found out how to achieve my goal...

@FriedrichWeinmann
Copy link
Member

Access the error

$_

fail silently

Nope, sorry.

ErrorVariable

That's a builtin Parameter that comes with all commands.
Doesn't help here - when Invoke-PSFProtectedCommand fails, it does so with maximum prejudice

But those params (like others) are not included in the detailed command help

Damn, that should not have happened of course.
Will need to update my tests (which should have caught that) and backfill the help for all Cmdlets that slipped through the cracks here (I'm opening a new issue for that so I don't forget).

Anyway, I think the reset capability I'll include in the next release should address your issue.
I'll look into supporting -ErrorAction and -ErrorVariable or alternatives for a natively silent flow, but can't promise anything specific on that front, simply due to the high risk of breaking things or overloading just what this command does.
It has already become quite complex as it is ^^

@Callidus2000
Copy link
Author

Access the error

$_

Not working at all or just misunderstood. Example function:

function Invoke-MyScript {
    [CmdletBinding()]
    param (
        [scriptblock]$ScriptBlock,
        [string]$LoggingAction
    )
    Invoke-PSFProtectedCommand -Action $LoggingAction -ScriptBlock $ScriptBlock  -Level host 
    Write-PSFMessage -Level Critical "Accessing the error, Variant 1: $_"
    Write-PSFMessage -Level Critical "Accessing the error, Variant 2: $($Error[0]|Out-String)"
    Write-PSFMessage -Level Critical "Accessing the error, Variant 3: $(Get-Error|Out-String)"
}
$invokeCommandParam = @{
    scriptBlock   = [scriptblock]::Create("`$result = 1 / 0")
    LoggingAction = "Will Fail"
}
invoke-MyScript @invokeCommandParam

Executed I see as a result

  • Variant 1 $_ show noting,
  • Variant 2 and 3 $Error[0] and Get-Error show a desired output.

Runspace Anomaly?

The solution only works if I call the function from the same context, e.g. if I put the above code in a PS1 file and execute it. In my real life scenario the function is provided by a module (based on Invoke-PSMDTemplate -TemplateName PSFProject). If I call the module script function from commandline/script, neither of the three 'Show me the inner error/exception' variants produces any output. Funny thing is that Get-Error called from the command line show the inner exception...

Cost some time to find the cause lies (partly) in providing the function in the module....

@FriedrichWeinmann
Copy link
Member

Alright, I messed up a little with the error event:
It expects $args[0] there:

function Invoke-MyScript {
    [CmdletBinding()]
    param (
        [scriptblock]$ScriptBlock,
        [string]$LoggingAction
    )
    Invoke-PSFProtectedCommand -Action $LoggingAction -ScriptBlock $ScriptBlock -Level host -ErrorEvent {
		Write-PSFMessage -Level Critical "Accessing the error, Variant 1: $($args[0])"
	}
}
$invokeCommandParam = @{
    scriptBlock   = [scriptblock]::Create("`$result = 1 / 0")
    LoggingAction = "Will Fail"
}
invoke-MyScript @invokeCommandParam

Supporting $_ should still be an option, so I'll see that I add that for the next release.

And no, PSFramework does not expect you to define the scriptblock you run with Invoke-PSFProtectedCommand from outside the caller's context. I am only willing to go so far when hacking the PowerShell system to make my magic happen ^^

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

No branches or pull requests

2 participants