锁定桌面剪贴板不可用响应

桌面剪贴板写入失败转为稳定 host_error

桌面剪贴板读取失败转为稳定 host_error

桌面分享写入剪贴板失败复用稳定不可用响应

桌面壳配置检查反查剪贴板不可用边界
This commit is contained in:
2026-06-20 12:27:45 +08:00
parent d777ad6633
commit 12ab5ef064
3 changed files with 59 additions and 4 deletions
@@ -1921,9 +1921,14 @@ for (const snippet of [
'write_desktop_clipboard_text(app, text)',
'read_desktop_clipboard_text(app)',
'normalize_clipboard_text(&text)',
'clipboard_write_unavailable_response',
'clipboard_read_unavailable_response',
'required_string_payload(request, "text")',
'truncated.chars().count()',
'"text": text',
'"clipboard write unavailable"',
'"clipboard read unavailable"',
'clipboard_unavailable_responses_are_stable',
]) {
if (!desktopHostBridgeClipboardSource.includes(snippet)) {
throw new Error(`desktop shell clipboard module is missing ${snippet}`);
@@ -27,6 +27,26 @@ pub(crate) fn read_desktop_clipboard_text(app: &tauri::AppHandle) -> Result<Stri
.map_err(|error| error.to_string())
}
pub(crate) fn clipboard_write_unavailable_response(
request: &HostBridgeRequest,
) -> HostBridgeResponse {
failed(
request.id.clone(),
"host_error",
"clipboard write unavailable",
)
}
pub(crate) fn clipboard_read_unavailable_response(
request: &HostBridgeRequest,
) -> HostBridgeResponse {
failed(
request.id.clone(),
"host_error",
"clipboard read unavailable",
)
}
pub(crate) fn write_desktop_host_bridge_clipboard_text(
app: &tauri::AppHandle,
request: &HostBridgeRequest,
@@ -38,7 +58,7 @@ pub(crate) fn write_desktop_host_bridge_clipboard_text(
match write_desktop_clipboard_text(app, text) {
Ok(()) => ok(request.id.clone(), json!(true)),
Err(error) => failed(request.id.clone(), "host_error", error),
Err(_) => clipboard_write_unavailable_response(request),
}
}
@@ -53,7 +73,7 @@ pub(crate) fn read_desktop_host_bridge_clipboard_text(
"text": text,
}),
),
Err(error) => failed(request.id.clone(), "host_error", error),
Err(_) => clipboard_read_unavailable_response(request),
}
}
@@ -92,4 +112,32 @@ mod tests {
})
);
}
#[test]
fn clipboard_unavailable_responses_are_stable() {
let write_response = clipboard_write_unavailable_response(&HostBridgeRequest {
bridge: "GenarrativeHostBridge".to_string(),
version: 1,
id: "clipboard-write".to_string(),
method: "clipboard.writeText".to_string(),
payload: None,
});
let read_response = clipboard_read_unavailable_response(&HostBridgeRequest {
bridge: "GenarrativeHostBridge".to_string(),
version: 1,
id: "clipboard-read".to_string(),
method: "clipboard.readText".to_string(),
payload: None,
});
assert!(!write_response.ok);
let write_error = write_response.error.expect("clipboard write error");
assert_eq!(write_error.code, "host_error");
assert_eq!(write_error.message, "clipboard write unavailable");
assert!(!read_response.ok);
let read_error = read_response.error.expect("clipboard read error");
assert_eq!(read_error.code, "host_error");
assert_eq!(read_error.message, "clipboard read unavailable");
}
}
@@ -1,4 +1,6 @@
use crate::host_bridge::clipboard::write_desktop_clipboard_text;
use crate::host_bridge::clipboard::{
clipboard_write_unavailable_response, write_desktop_clipboard_text,
};
use crate::host_bridge::protocol::{failed, ok, HostBridgeRequest, HostBridgeResponse};
use crate::shell::webview::WEB_APP_ORIGIN;
use serde_json::json;
@@ -194,7 +196,7 @@ pub(crate) fn open_desktop_host_bridge_share(
"action": "copied_to_clipboard"
}),
),
Err(error) => failed(request.id.clone(), "host_error", error),
Err(_) => clipboard_write_unavailable_response(request),
}
}