fix(clipboard): hardened WSL PowerShell fallback for headless environments

- Raised PowerShell timeout to 8s and swallowed reap errors to prevent unhandled throws on WSL interop.
- Fixed fallback logic so arboard is skipped when no display server is present on headless WSL.
- Added test coverage for the headless WSL short-circuit path.
This commit is contained in:
can1357
2026-05-25 14:05:48 +02:00
parent 79f6bf4f76
commit 81cec1c38b
2 changed files with 30 additions and 5 deletions
+14 -3
View File
@@ -1,6 +1,7 @@
import { execSync } from "node:child_process";
import type { ClipboardImage } from "@oh-my-pi/pi-natives";
import * as native from "@oh-my-pi/pi-natives";
import { logger } from "@oh-my-pi/pi-utils";
function hasDisplay(): boolean {
return process.platform !== "linux" || Boolean(process.env.DISPLAY || process.env.WAYLAND_DISPLAY);
@@ -80,7 +81,7 @@ if ($img -ne $null) {
}
`;
const POWERSHELL_TIMEOUT_MS = 5000;
const POWERSHELL_TIMEOUT_MS = 8000;
/**
* Read a clipboard image through the Windows host's PowerShell.
@@ -104,6 +105,12 @@ async function readImageViaPowerShell(): Promise<ClipboardImage | null> {
try {
stdout = await new Response(proc.stdout).text();
await proc.exited;
} catch (err) {
// powershell.exe is a Windows process reached over WSL interop; if it
// doesn't reap cleanly, swallow the error so the dispatcher can fall
// through to the native bridge instead of throwing.
logger.warn("clipboard: powershell read failed", { error: String(err) });
return null;
} finally {
clearTimeout(timer);
}
@@ -136,8 +143,12 @@ export async function readImageFromClipboard(): Promise<ClipboardImage | null> {
if (isWsl()) {
const image = await readImageViaPowerShell();
if (image) return image;
// Fall through: arboard may still succeed on a future WSLg release.
} else if (!hasDisplay()) {
// Fall through: arboard may still succeed on a future WSLg release —
// but only when we actually have a display server. Headless WSL has
// no display, so arboard would reject anyway.
}
if (!hasDisplay()) {
return null;
}