Private/Write-ErrorDetail.ps1

function Write-ErrorDetail {
    <#
        .SYNOPSIS
            Writes the details of an ErrorRecord to the warning stream, including the exception type and message,
            the function name, script file and line number where the error occurred, and the full script stack trace.
            Used to surface the origin of errors thrown from app, shared and private functions.
    #>

    [OutputType([System.Void])]
    [CmdletBinding(SupportsShouldProcess = $false)]
    param (
        [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline)]
        [ValidateNotNull()]
        [System.Management.Automation.ErrorRecord] $ErrorRecord,

        [Parameter(Mandatory = $false)]
        [ValidateNotNullOrEmpty()]
        [System.String] $LastFrame
    )

    process {
        # Report the exception type and message
        Write-Warning -Message "Error: [$($ErrorRecord.Exception.GetType().FullName)] $($ErrorRecord.Exception.Message)"

        # Report where the error originated - function name, script file and line number
        $Invocation = $ErrorRecord.InvocationInfo
        if ($null -ne $Invocation -and $Invocation.ScriptLineNumber -gt 0) {
            $FunctionName = if ($null -ne $Invocation.MyCommand -and -not [System.String]::IsNullOrWhiteSpace($Invocation.MyCommand.Name)) {
                $Invocation.MyCommand.Name
            }
            else {
                "<ScriptBlock>"
            }
            $ScriptName = if ([System.String]::IsNullOrWhiteSpace($Invocation.ScriptName)) { "<No file>" } else { $Invocation.ScriptName }
            Write-Warning -Message "Error source: '$FunctionName' in '$ScriptName' at line $($Invocation.ScriptLineNumber), char $($Invocation.OffsetInLine)."
            if (-not [System.String]::IsNullOrWhiteSpace($Invocation.Line)) {
                Write-Warning -Message "Error line: $($Invocation.Line.Trim())"
            }
        }

        # Report the full script stack trace - each frame includes the function name, script file and line number
        if (-not [System.String]::IsNullOrWhiteSpace($ErrorRecord.ScriptStackTrace)) {
            Write-Warning -Message "Stack trace:"
            foreach ($Frame in ($ErrorRecord.ScriptStackTrace -split "\r?\n")) {
                Write-Warning -Message " $Frame"

                # Stop after the specified function so that frames from the caller's context are not displayed
                if ($PSBoundParameters.ContainsKey("LastFrame") -and $Frame -match "^at $LastFrame[<,]") {
                    break
                }
            }
        }
    }
}