Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

  • PowerShell® is a frequently used scripting language available for Linux, MacOS, Windows and other platforms.
  • JS7 offers the JS7 - PowerShell Module for simplified access to the JS7 - REST Web Service API
  • This article explains some common ways of handling run-time errors in PowerShell® job scripts.

Scenario

  • The examples below use a common scenario to raise a run-time error:
    • a workflow is assigned a lookup_path variable that specifies a directory which is tested in a later job to see whether or not it exists.
    • the PowerShelll PowerShell® Test-Path cmdlet is used to test for the existence of the directory. The functioning of the cmdlet is that:
      • it returns $True if the directory exists and $False if it does not exist,
      • it raises an exception if the cmdlet parameter for the directory includes a $Null value.
  • In a perfect world script developers would check if a variable holds a null value before even using it. However, this world is far from being perfect. In addition, the script code required to perfectly check variables for null values would exceed by far the amount of code required for the effective processing of business logic. As a result, hardly anybody implements such checks.
  • The examples below can be executed by adding an order, for example from the JOC Cockpit Workflows view in two variants:
    • add the order without modification of the lookup_path variable: the example will run without error,
    • add the order and modify the value of the lookup_path variable to an empty string: an error will be raised:

      x

PowerShell Profiles

PowerShell® profiles can be used to modify defaults available with PowerShell®.

  • A PowerShell® profile will be used if available from one of the locations provided by the platform (Windows, Linux, MacOS etc., please check applicability of profiles for your platform).
  • You can examine the global $PROFILE variable to verify applicable profile locations:
    • PS C:\> $PROFILE | Get-Member
    • Profile locations typically are applied from the following properties in descending order. This means that all profiles from aall all locations are applied if available.

      • $PROFILE.AllUsersAllHosts
      • $PROFILE.AllUsersCurrentHost
      • $PROFILE.CurrentUserAllHosts
      • $PROFILE.CurrentUserCurrentHost
  • By default JS7 does not make use of a specific PowerShell® profile, instead the above order of available profiles applies.

...

This situation boils down to defaults available with PowerShell®.

  • Built-in defaults of PowerShell® apply.
  • Defaults that are modified by a PowerShell® profile.

Continue Processing in case of Errors

...

This is the most undesirable scenario as it implies that the PowerShell® script:

  • continues and might perform very bad things, for example if a cmdlet such as Remove-Item -Path /$env:LOOKUP_PATH -Recurse would be used with $env:LOOKUP_PATH evaluating to null.
  • completes with an exit code 0 signaling success if the last cmdlet executed with the script was successful. JS7 cannot know that an error occurred and users will not be notified.

...

This is a somewhat acceptable scenario as it prevents the PowerShell® script from continuing and it raises an exception that is recognized by JS7 and which will fail the job.

...

Code Block
languagepowershell
titleExample how use PowerShell PowerShell® global error handling
#!/usr/bin/env pwsh

# global setting: stop execution in case of errors
$ErrorActionPreference = "stop"

$lookupPath = $env:LOOKUP_PATH
if ( !$lookupPath )
{
  $lookupPath = $null
}

If ( Test-Path -Path $lookupPath -PathType container )
{
	Write-Host "path found: $env:LOOKUP_PATH"
} else {
	Write-Host "path not found: $env:LOOKUP_PATH"
}

...

This situation boils down to defaults available with PowerShell® and to the handling of errors with jobs.

  • Built-in defaults of PowerShell® apply.
  • Defaults that are modified by a PowerShell® profile.
  • Error detection by JS7, returning exit codes and controlling exceptions.

...

Code Block
languagepowershell
titleExample how to make JS7 detect PowerShell PowerShell® errors
#!/usr/bin/env pwsh

# use of Write-Error cmdlet
# consider the job options to fail if output to stderr is detected

$lookupPath = $env:LOOKUP_PATH
if ( !$lookupPath )
{
  Write-Error "empty lookup path not accepted"
}

if ( Test-Path -Path $lookupPath -PathType container -ErrorAction stop )
{
	Write-Host "path found: $env:LOOKUP_PATH"
} else {
	Write-Host "path not found: $env:LOOKUP_PATH"
}

...

Setting a non-zero exit code in a PowerShell® script performs two operations:

...

Code Block
languagebash
titleExample how to exit a PowerShell PowerShell® script with an exit code value
#!/usr/bin/env pwsh

# use of Write-Error cmdlet
# exit script with an exit code 

$lookupPath = $env:LOOKUP_PATH
if ( !$lookupPath )
{
  Write-Host "empty lookup path not accepted"
  Exit(12)
}

if ( Test-Path -Path $lookupPath -PathType container -ErrorAction stop )
{
	Write-Host "path found: $env:LOOKUP_PATH"
} else {
	Write-Host "path not found: $env:LOOKUP_PATH"
}

Control Exceptions with Try/Catch

Use of the PowerShell PowerShell® Try/Catch instructions offers full control of error handling in case of errors:

...

Code Block
languagepowershell
titleExample how to use try/catch to control PowerShell PowerShell® script exceptions
#!/usr/bin/env pwsh

$lookupPath = $env:LOOKUP_PATH
if ( !$lookupPath )
{
  $lookupPath = $null
}

try {
	If ( Test-Path -Path $lookupPath -PathType container )
	{
		Write-Host "path found: $env:LOOKUP_PATH"
	} else {
		Write-Host "path not found: $env:LOOKUP_PATH"
	}
} catch {
    $message = $_.Exception | Format-List -Force | Out-String
    Write-Error "error occurred: $message"
}

...