Private/ConvertTo-UKGError.ps1

function ConvertTo-UKGError {
    <#
    .SYNOPSIS
        Converts API error responses to PowerShell-friendly error records.

    .DESCRIPTION
        Parses UKG API error responses and creates appropriate ErrorRecord objects
        with meaningful error IDs and categories.

    .PARAMETER Response
        The error response from the API.

    .PARAMETER StatusCode
        The HTTP status code of the response.

    .PARAMETER Exception
        The exception that was thrown during the request.
    #>

    [CmdletBinding()]
    param(
        [Parameter()]
        [object]$Response,

        [Parameter()]
        [int]$StatusCode,

        [Parameter()]
        [System.Exception]$Exception
    )

    # Default error information
    $errorId = 'UKGApiError'
    $errorMessage = 'An error occurred while calling the UKG API.'
    $errorCategory = [System.Management.Automation.ErrorCategory]::NotSpecified

    # Map status codes to categories
    $categoryMap = @{
        400 = [System.Management.Automation.ErrorCategory]::InvalidArgument
        401 = [System.Management.Automation.ErrorCategory]::AuthenticationError
        403 = [System.Management.Automation.ErrorCategory]::PermissionDenied
        404 = [System.Management.Automation.ErrorCategory]::ObjectNotFound
        409 = [System.Management.Automation.ErrorCategory]::ResourceExists
        422 = [System.Management.Automation.ErrorCategory]::InvalidData
        429 = [System.Management.Automation.ErrorCategory]::LimitsExceeded
        500 = [System.Management.Automation.ErrorCategory]::NotSpecified
        502 = [System.Management.Automation.ErrorCategory]::ConnectionError
        503 = [System.Management.Automation.ErrorCategory]::ResourceUnavailable
        504 = [System.Management.Automation.ErrorCategory]::OperationTimeout
    }

    if ($categoryMap.ContainsKey($StatusCode)) {
        $errorCategory = $categoryMap[$StatusCode]
    }

    # Parse the response if available
    if ($null -ne $Response) {
        # Handle different response formats
        if ($Response -is [string]) {
            try {
                $Response = $Response | ConvertFrom-Json
            }
            catch {
                # Response is plain text
                $errorMessage = $Response
            }
        }

        if ($Response.PSObject.Properties.Name -contains 'code') {
            $errorId = "UKG_$($Response.code)"
        }

        if ($Response.PSObject.Properties.Name -contains 'message') {
            $errorMessage = $Response.message
        }
        elseif ($Response.PSObject.Properties.Name -contains 'error') {
            $errorMessage = $Response.error
        }
        elseif ($Response.PSObject.Properties.Name -contains 'error_description') {
            $errorMessage = $Response.error_description
        }

        # Include validation errors if present
        if ($Response.PSObject.Properties.Name -contains 'errors' -and $Response.errors) {
            $validationErrors = @()
            foreach ($err in $Response.errors) {
                if ($err.PSObject.Properties.Name -contains 'field' -and $err.PSObject.Properties.Name -contains 'message') {
                    $validationErrors += "$($err.field): $($err.message)"
                }
                elseif ($err -is [string]) {
                    $validationErrors += $err
                }
                else {
                    $validationErrors += ($err | ConvertTo-Json -Compress)
                }
            }
            if ($validationErrors.Count -gt 0) {
                $errorMessage += "`nValidation errors:`n - " + ($validationErrors -join "`n - ")
            }
        }
    }

    # Add status code to message if available
    if ($StatusCode -gt 0) {
        $errorMessage = "HTTP $StatusCode : $errorMessage"
    }

    # Create the exception
    $actualException = if ($null -ne $Exception) {
        New-Object System.Exception($errorMessage, $Exception)
    }
    else {
        New-Object System.Exception($errorMessage)
    }

    # Create and return the error record
    $errorRecord = New-Object System.Management.Automation.ErrorRecord(
        $actualException,
        $errorId,
        $errorCategory,
        $null
    )

    return $errorRecord
}