Skip to main content

Unwrap error records (e.g. $Error[0]) for cleaner display.

function ConvertFrom-ErrorRecord
{
    <#
    .SYNOPSIS
        Unwrap error records (e.g. $Error[0]) for cleaner display.

    .DESCRIPTION
        Whenever PowerShell raises an error, an error record is written to
        $error which is an array storing the last errors that occurred.

        The function uses two parameter sets, and valid ErrorRecord objects are
        automatically bound to $Record. If an object of different type is
        encountered that cannot be handled by this function, it is bound to $Alien.

        You can try and manually extract relevant error information from
        ErrorRecord objects, or you can use this function.

    .PARAMETER Record
        The error record.

    .PARAMETER Alien
        An unidentified object.

    .LINK
        https://blog.idera.com/database-tools/converting-error-records

    .EXAMPLE
        PS > try {
        PS >     1 / 0
        PS > }
        PS > catch {
        PS >     $_ | ConvertFrom-ErrorRecord | Format-List
        PS > }
        Exception : Attempted to divide by zero.
        Reason    : RuntimeException
        Target    :
        Script    : /Users/jon/Downloads/error-record.ps1
        Line      : 69
        Column    : 13
    #>
    [OutputType([PSCustomObject])]
    [CmdletBinding(DefaultParameterSetName = 'ErrorRecord')]
    param
    (
        [Management.Automation.ErrorRecord]
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ErrorRecord', Position = 0)]
        $Record,

        [Object]
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'Unknown', Position = 0)]
        $Alien
    )

    process
    {
        if ($PSCmdlet.ParameterSetName -eq 'ErrorRecord')
        {
            [PSCustomObject]@{
                Exception = $Record.Exception.Message
                Reason = $Record.CategoryInfo.Reason
                Target = $Record.CategoryInfo.TargetName
                Script = $Record.InvocationInfo.ScriptName
                Line = $Record.InvocationInfo.ScriptLineNumber
                Column = $Record.InvocationInfo.OffsetInLine
            }
        }
        else
        {
            Write-Warning "$Alien"
        }
    }
}