5

I'm trying to write a PowerShell script which sends a Slack notification whenever our build system in unable to push Docker images to Docker Hub. How can I detect and handle the Process exited with code 1 from the docker push command? I've tried the following, but the catch block isn't called.

try {
  docker push $dockerImage;
}catch{
  #Send error details to Slack
}
1

1 Answer 1

6
  • In Windows PowerShell and PowerShell (Core) up to version 7.3.x, calls to external programs (such as docker) never cause a statement-terminating error[1] that you can trap with try / catch; similarly, stderr output from external program is (rightfully) not considered error output by PowerShell, and therefore $ErrorActionPreference = 'Stop' has no effect on it (for legacy exceptions in Windows PowerShell, see this answer).

    • In PowerShell (Core) v7.4+, opt-in integration with PowerShell's error handling is available, via the $PSNativeCommandUseErrorActionPreference preference variable.

      • If you set this variable to $true, any external-program call that reports a nonzero exit code automatically triggers a PowerShell error in response (obviating the need for explicit $LASTEXITCODE -ne 0 checks), which then integrates with PowerShell's own error handling.[2]
        That is, with the $ErrorActionPreference preference variable set to 'Stop', any external program reporting a nonzero exit code will then result in a script-terminating (fatal by default) error.
    • In general, note that a statement-terminating PowerShell error (which can be caught with try / catch) does occur if PowerShell fails to even launch a command, such as when you supply a non-existent executable name or path; e.g.:

      try   { nosuchexe foo bar }
      catch { Write-Warning "Failed to invoke nosuchexe: $_" }
      
  • The automatic $LASTEXITCODE variable reflects the process exit code of the most recently executed external program. By convention, exit code 0 signals success, anything else an error condition.

Therefore:

docker push $dockerImage
if ($LASTEXITCODE -ne 0) {
  #Send error details to Slack
}

See also:

  • This answer has more information on exit-code processing in PowerShell.

[1] The only exception is a bug, present in Windows PowerShell and historically in PowerShell (Core) up to the no-longer-supported v7.1.x, where the combination of redirecting stderr output (2> or *>) with $ErrorActionPreference = 'Stop' unexpectedly causes a script-terminating error if there's actual stderr output - see this answer.

[2] Unfortunately, as of PowerShell 7.4.x, the automatically triggered PowerShell error is a non-terminating error rather than a statement-terminating one; the latter would make more sense, as it would allow it to be selectively caught with a try statement - see GitHub issue #18368.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't think it's a good idea have large random pos/neg numbers as failing result codes from `$LASTEXITCODE.
@not2qubit, indeed, small, positive numbers are typical, and, for cross-platform use you're limited to positive numbers between 0 and 255. Technically, however, process exit codes on Windows can be any signed 32-bit integer value ([int]/ System.Int32, in PowerShell / .NET terms).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.