diff --git a/samy.ps1 b/samy.ps1 index 720253d..9b0b966 100644 --- a/samy.ps1 +++ b/samy.ps1 @@ -1324,23 +1324,59 @@ $jsContent } function Send-JSON { - param($Context, $Object) - if (-not $Context -or -not $Context.Response) { - return - } + [CmdletBinding()] + param( + $Context, + $Object + ) - # If caller gave us $null, reply with an empty array instead of blowing up - if ($null -eq $Object) { - $Object = @() - } + if (-not $Context -or -not $Context.Response) { + return + } + + try { + # 🔹 Normalize $Object so we never feed $null to GetBytes + if ($null -eq $Object) { + Write-LogHybrid "Send-JSON called with `$null object; returning empty JSON array." Warning Printers -LogToEvent + $json = '[]' + } + else { + # If ConvertTo-Json fails, force an empty array string instead of bubbling $null + try { + $json = $Object | ConvertTo-Json -Depth 5 -ErrorAction Stop + } + catch { + Write-LogHybrid "Send-JSON serialization failed: $($_.Exception.Message); returning empty JSON array." Error Printers -LogToEvent + $json = '[]' + } + } + + # 🔹 Final safety: ensure we always pass a *string* to GetBytes + $json = [string]$json + + $bytes = [Text.Encoding]::UTF8.GetBytes($json) + $Context.Response.ContentType = 'application/json' + $Context.Response.ContentLength64 = $bytes.Length + $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length) + $Context.Response.OutputStream.Close() + } + catch { + # Last-resort error handling – don't let the whole request crash + Write-LogHybrid "Send-JSON fatal error: $($_.Exception.Message)" Error Printers -LogToEvent + try { + $fallback = '[]' + $bytes = [Text.Encoding]::UTF8.GetBytes($fallback) + $Context.Response.ContentType = 'application/json' + $Context.Response.ContentLength64 = $bytes.Length + $Context.Response.OutputStream.Write($bytes, 0, $bytes.Length) + $Context.Response.OutputStream.Close() + } + catch { + # If even this fails, just give up silently – we've already logged it. + } + } +} - $json = $Object | ConvertTo-Json -Depth 5 - $bytes = [Text.Encoding]::UTF8.GetBytes($json) - $Context.Response.ContentType = 'application/json' - $Context.Response.ContentLength64 = $bytes.Length - $Context.Response.OutputStream.Write($bytes,0,$bytes.Length) - $Context.Response.OutputStream.Close() - } #endregion HTTP responder helpers function Invoke-TasksCompleted {