Citrix Virtual Apps and Desktops SDK

about_Broker_ErrorHandling

Topic

Citrix Broker SDK - Error Handling

Short Description

Describes broker errors generated by cmdlets and how to access them.

Long Description

The broker SDK cmdlets report errors through the class SdkErrorRecord, which is a subclass of the standard Powershell error record class System.Management.Automation.ErrorRecord. SdkErrorRecord contains:

  • A short string to describe the error status code. This is implemented as a public property named Status.
  • A dictionary of key-value pairs containing additional data specific to the cmdlet. This is implemented as a public property named ErrorData of type Dictionary<string, string>.

The error status property always has a value. Populating the error data dictionary is optional. The number of entries within the dictionary, the content of the entries, and the exact format of the key and value data is specific to each cmdlet.

You can access an SdkErrorRecord object using the standard Powershell cmdlet ErrorVariable parameter. The type of object returned by ErrorVariable depends on whether the error is terminating or non-terminating.

Non-Terminating Errors

For non-terminating errors, each object in the returned ErrorVariable array is simply an instance of type SdkErrorRecord.

Terminating Errors

For terminating errors, the object returned by ErrorVariable is of type System.Management.Automation.CmdletInvocationException.

For non-terminating errors that are escalated as terminating errors (through the “ErrorAction stop” argument), the object returned by ErrorVariable is of type System.Management.Automation.ActionPreferenceStopException.

CmdletInvocationException and ActionPreferenceStopException are subclasses of the base class System.Management.Automation.RuntimeException, which exposes the SdkErrorRecord object through its ErrorData property.

Class SdkOperationException

SdkErrorRecord’s Exception property holds an instance of custom exception class SdkOperationException, which also contains the error status code and data dictionary from SdkErrorRecord.

The SDK cmdlets generate errors in response to exceptions generated by the underlying system or by the cmdlet detecting errors locally and instantiating appropriate exception types. Such exceptions, which represent the original cause of the terminating error, are specified in SdkOperationException’s InnerException property.

For terminating errors, use Powershell scripts to trap SdkOperationException and access additional error information and the originating exception.

Review Of Powershell Error Handling Behavior

Powershell scripts can access error information using the following methods:

  • Read error records from the $error arraylist.
  • Get the cmdlet to return error records using the standard ErrorVariable cmdlet parameter.
  • Use trap blocks to catch exceptions for terminating errors.

The type of the error record that Powershell puts in the $error arraylist and returns through the ErrorVariable cmdlet parameter depends on whether the error is terminating or non-terminating, and whether the “ErrorAction continue” or “ErrorAction stop” cmdlet parameters are specified (that turn terminating errors into non-terminating ones, and vice versa).

For the combinations of error types (terminating, non-terminating) and error actions (stop, continue), the following statements describe the relationship between:

  • The type of object contained in the Powershell $error arraylist.
  • The type of object returned by the ErrorVariable cmdlet parameter (assuming the script can continue after a terminating error).
  • The type of the exception that is thrown (where applicable).

Non-terminating errors with ErrorAction=Continue, $error type=SdkErrorRecord, and ErrorVariable type=SdkErrorRecord do not throw an exception.

Terminating errors with ErrorAction=Stop, $error type=ErrorRecord, and ErrorVariable type=CmdletInvocationException throw an SdkOperationException exception.

Non-terminating errors with ErrorAction=Stop, $error type=ErrorRecord, and ErrorVariable type=ActionPreferenceOperationException do not throw an exception.

Terminating errors with ErrorAction=Continue, $error type=ErrorRecord, and ErrorVariable type= CmdletInvocationException throw an SdkOperationException exception.

ActionPreferenceOperationException and CmdletInvocationException are subclasses of System.Management.Automation.RuntimeException.

Accessing Error Record Data

The Powershell code sample below demonstrates how to access error information programmatically with the ErrorVariable cmdlet parameter and a trap block.

    # Trap exceptions generated from terminating errors
    trap  [Exception] {
        write ""
        write "TRAP BLOCK : BEGIN”
        if($_.Exception.GetType().Name -eq "SdkOperationException")
        {
            $sdkOpEx = $_.Exception
            # show error status
            write $("SdkOperationException.Status = " + $sdkOpEx.Status)
            # show error data dictionary
            write $("SdkOperationException.ErrorData=")
            write $("SdkOperationException.InnerException = " + $sdkOpEx.InnerException)
            $_.Exception.ErrorData
        }
        continue #could also call break here to halt script execution
        write "TRAP BLOCK : END"
    }

<!--NeedCopy-->
    ###########################################################################
    ## Run tests 1 to 4, below, in turn to examine terminating and
    ## non-terminating error behavior.
    ###########################################################################

<!--NeedCopy-->
    # Test 1: Invoke cmdlet that generates a terminating error:
    #         New-BrokerCatalog throws terminating error if a
    #         catalog with the supplied name already exists.
    #
    #New-BrokerCatalog -Name "AlreadyExists" -AllocationType Random -ProvisioningType Manual -SessionSupport SingleSession -PersistUserChanges OnLocal -MachinesArePhysical $true -ErrorVariable ev
#

<!--NeedCopy-->
    # Test 2: Force script execution to continue after a terminating error.
    #
    #New-BrokerCatalog -Name "AlreadyExists" -AllocationType Random -ProvisioningType Manual -SessionSupport SingleSession -PersistUserChanges OnLocal -MachinesArePhysical $true -ErrorVariable ev -ErrorAction continue
#

<!--NeedCopy-->
    # Test 3: Invoke cmdlet that generates a non-terminating error:
    #         Get-BrokerCatalog generates a non-terminating error if a catalog
    #         with the specified name doesn't exist.
    #
    #Get-BrokerCatalog -Name "IDontExist" -ErrorVariable ev
#

<!--NeedCopy-->
    # Test 4 – Force script execution to halt after a non-terminating error.
    #
    #Get-BrokerCatalog -Name "IDontExist" -ErrorVariable ev -ErrorAction "stop"
    write ""
    write "GET ERROR INFORAMTION: BEGIN"
    $sdkErrRecord = $null
    if($ev[0].GetType().Name -eq "SdkErrorRecord")
    {
        $sdkErrRecord = $ev[0]
    }
    elseif($ev[0].GetType().BaseType.FullName -eq "System.Management.Automation.RuntimeException")
    {
        $sdkErrRecord = $ev[0].ErrorRecord
    }
    else
    {
      write ("UNKNOWN ERROR VARIABLE TYPE:")
      $ev[0].GetType().Name
    }
    if($sdkErrRecord -ne $null)
    {
        write ("Have sdkErrRecord:")
        write ("  Type Name = " + $sdkErrRecord.GetType().FullName)
        write ("  Status = " + $sdkErrRecord.Status)
        write ("  Exception type = " + $sdkErrRecord.Exception.GetType().FullName)
        write ("  ErrorData = ")
        $sdkErrRecord.ErrorData
        write ("  FullyQualifiedErrorId = " + $sdkErrRecord.FullyQualifiedErrorId)
    }
    write "GET ERROR INFORAMTION: END"
#

<!--NeedCopy-->
about_Broker_ErrorHandling