Private/New-HaloError.ps1
|
using namespace System.Collections.Generic using namespace System.Management.Automation function New-HaloError { [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Justification = 'Private function - no need to support.')] param ( # The source error record to normalize into HaloAPI error output. [Parameter( Mandatory, ParameterSetName = 'ErrorRecord' )] [errorrecord]$ErrorRecord, # Indicates whether the source error is expected to contain an HTTP response object. [Parameter( ParameterSetName = 'ErrorRecord' )] [switch]$HasResponse, # A module-generated error message to throw when no error record is available. [Parameter( Mandatory, ParameterSetName = 'ModuleMessage' )] [string]$ModuleMessage ) Write-Verbose 'Generating Halo error output.' $ExceptionMessage = [Hashset[String]]::New() $APIResultMatchString = '*The Halo API said*' $HTTPResponseMatchString = '*The API returned the following HTTP*' if ($ErrorRecord.ErrorDetails) { Write-Verbose 'ErrorDetails contained in error record.' Write-Debug ('Raw ErrorDetails: {0}' -f ($ErrorRecord.ErrorDetails | Out-String)) $ErrorDetailsIsJson = Test-Json -Json $ErrorRecord.ErrorDetails -ErrorAction SilentlyContinue if ($ErrorDetailsIsJson) { Write-Verbose 'ErrorDetails is JSON.' $ErrorDetails = $ErrorRecord.ErrorDetails | ConvertFrom-Json Write-Debug ('Raw error details: {0}' -f ($ErrorDetails | Out-String)) if ($null -ne $ErrorDetails) { if (($null -ne $ErrorDetails.resultCode) -and ($null -ne $ErrorDetails.errorMessage)) { Write-Verbose 'ErrorDetails contains resultCode and errorMessage.' $ExceptionMessage.Add(('The Halo API said {0}: {1}.' -f $ErrorDetails.resultCode, $ErrorDetails.errorMessage)) | Out-Null } elseif (($null -ne $ErrorDetails.ClassName) -and ($null -ne $ErrorDetails.Message)) { Write-Verbose 'ErrorDetails contains ClassName and Message.' $ExceptionMessage.Add(('The Halo API said {0}: {1}' -f $ErrorDetails.ClassName, $ErrorDetails.Message)) | Out-Null } elseif ($null -ne $ErrorDetails.Message) { Write-Verbose 'ErrorDetails contains Message.' $ExceptionMessage.Add(('The Halo API said {0}' -f $ErrorDetails.Message)) | Out-Null } elseif ($null -ne $ErrorDetails.error) { Write-Verbose 'ErrorDetails contains error.' $ExceptionMessage.Add(('The Halo API said {0}.' -f $ErrorDetails.error)) | Out-Null } elseif ($null -ne $ErrorDetails) { Write-Verbose 'ErrorDetails is not null.' $ExceptionMessage.Add(('The Halo API said {0}.' -f $ErrorRecord.ErrorDetails)) | Out-Null } else { Write-Verbose 'ErrorDetails is null.' $ExceptionMessage.Add('The Halo API returned an error.') | Out-Null } } else { Write-Verbose 'No ErrorDetails - or could not parse.' } } elseif ($ErrorRecord.ErrorDetails -like $APIResultMatchString -and $ErrorRecord.ErrorDetails -like $HTTPResponseMatchString) { $Errors = $ErrorRecord.ErrorDetails -split "`r`n" if ($Errors -is [array]) { ForEach-Object -InputObject $Errors { $ExceptionMessage.Add($_) | Out-Null } } elseif ($Errors -is [string]) { $ExceptionMessage.Add($_) } } else { Write-Verbose 'ErrorDetails was not JSON or a parseable string or array.' } } elseif (-not [String]::IsNullOrEmpty($ModuleMessage)) { throw $ModuleMessage } elseif ($ErrorRecord.Exception.Message) { throw $ErrorRecord.Exception.Message } else { $ExceptionMessage.Add('The Halo API returned an error but did not provide a result code or error message.') | Out-Null } if (($ErrorRecord.Exception.Response -and $HasResponse) -or ($ExceptionMessage -notlike $HTTPResponseMatchString)) { $Response = $ErrorRecord.Exception.Response Write-Debug ('Raw HTTP response: {0}' -f ($Response | Out-String)) if ($Response.StatusCode.value__ -and $Response.ReasonPhrase) { $ExceptionMessage.Add(('The API returned the following HTTP error response: {0} {1}' -f $Response.StatusCode.value__, $Response.ReasonPhrase)) | Out-Null } else { $ExceptionMessage.Add('The API returned an HTTP error response but did not provide a status code or reason phrase.') } } $Exception = [System.Exception]::New( $ExceptionMessage, $ErrorRecord.Exception ) $HaloError = [ErrorRecord]::New( $ErrorRecord, $Exception ) $UniqueExceptions = $ExceptionMessage | Get-Unique if ($UniqueExceptions.Count -gt 1) { $HaloError.ErrorDetails = [String]::Join("`r`n", $UniqueExceptions) } else { $HaloError.ErrorDetails = $UniqueExceptions } $PSCmdlet.ThrowTerminatingError($HaloError) } |