src/public/System/Write-AitherError.ps1
|
#Requires -Version 7.0 <# .SYNOPSIS Centralized error handler for AitherZero cmdlets .DESCRIPTION Provides standardized error handling and logging for all AitherZero cmdlets. Ensures consistent error reporting with full context for debugging. This is a private helper function. Use the Invoke-AitherErrorHandler helper function in cmdlets for cleaner error handling. .NOTES This is a private helper function for use within AitherZero cmdlets. #> function Write-AitherError { [CmdletBinding()] param( [Parameter(Mandatory)] [System.Management.Automation.ErrorRecord]$ErrorRecord, [Parameter(Mandatory)] [string]$CmdletName, [Parameter(Mandatory)] [string]$Operation, [hashtable]$Parameters = @{}, [switch]$ThrowOnError ) # Handle error action preference first to determine behavior $errorActionPreference = if ($PSBoundParameters.ContainsKey('ErrorAction')) { $PSBoundParameters.ErrorAction } else { 'Continue' } if ($errorActionPreference -eq 'Stop') { $ThrowOnError = $true } # Generate unique error ID for tracking $errorId = [System.Guid]::NewGuid().ToString() $timestamp = Get-Date # Build comprehensive error information $errorInfo = @{ ErrorId = $errorId Cmdlet = $CmdletName Operation = $Operation Error = $ErrorRecord.Exception.Message ErrorType = $ErrorRecord.Exception.GetType().FullName StackTrace = $ErrorRecord.ScriptStackTrace PositionMessage = $ErrorRecord.PositionMessage Parameters = $Parameters Timestamp = $timestamp ComputerName = if ($env:COMPUTERNAME) { $env:COMPUTERNAME } else { $env:HOSTNAME } UserName = if ($IsWindows) { [System.Security.Principal.WindowsIdentity]::GetCurrent().Name } else { $env:USER } PowerShellVersion = $PSVersionTable.PSVersion.ToString() OS = if ($IsWindows) { "Windows" } elseif ($IsLinux) { "Linux" } elseif ($IsMacOS) { "macOS" } else { "Unknown" } } # Log error with full context if (Get-Command Write-AitherLog -ErrorAction SilentlyContinue) { # If we are going to throw, suppress console logging to avoid duplication # The error will be displayed by the throw/exception mechanism $targets = if ($ThrowOnError -and $errorActionPreference -ne 'SilentlyContinue') { @('File') } else { $null } Write-AitherLog -Level Error -Message "Error in $CmdletName during $Operation" -Source $CmdletName -Exception $ErrorRecord.Exception -Data $errorInfo -Targets $targets } else { # Fallback logging if Write-AitherLog not available if (-not $ThrowOnError) { Write-Error "Error in $CmdletName during $Operation : $($ErrorRecord.Exception.Message)" -ErrorId $errorId } } # Create error object for pipeline output $errorObject = [PSCustomObject]@{ PSTypeName = 'AitherZero.Error' Success = $false ErrorId = $errorId Cmdlet = $CmdletName Operation = $Operation Error = $ErrorRecord.Exception.Message ErrorType = $ErrorRecord.Exception.GetType().FullName Timestamp = $timestamp Parameters = $Parameters StackTrace = $ErrorRecord.ScriptStackTrace } # Always output error object to pipeline Write-Output $errorObject if ($errorActionPreference -eq 'SilentlyContinue') { return } # Re-throw if requested if ($ThrowOnError) { throw $ErrorRecord } } |