补齐桌面壳插件失败观测
桌面剪贴板和通知插件异常记录日志 Rust 单测覆盖稳定错误和日志边界 配置门禁和文档同步桌面插件观测约束
This commit is contained in:
@@ -2065,6 +2065,10 @@ for (const snippet of [
|
||||
'write_desktop_clipboard_text(app, text)',
|
||||
'read_desktop_clipboard_text(app)',
|
||||
'normalize_clipboard_text(&text)',
|
||||
'log_desktop_clipboard_failure',
|
||||
'desktop clipboard failed for {label}: {error}',
|
||||
'log_desktop_clipboard_failure("write.text", &error)',
|
||||
'log_desktop_clipboard_failure("read.text", &error)',
|
||||
'clipboard_write_unavailable_response',
|
||||
'clipboard_read_unavailable_response',
|
||||
'required_string_payload(request, "text")',
|
||||
@@ -2073,6 +2077,7 @@ for (const snippet of [
|
||||
'"clipboard write unavailable"',
|
||||
'"clipboard read unavailable"',
|
||||
'clipboard_unavailable_responses_are_stable',
|
||||
'clipboard_failures_are_logged_without_exposing_native_detail',
|
||||
]) {
|
||||
if (!desktopHostBridgeClipboardSource.includes(snippet)) {
|
||||
throw new Error(`desktop shell clipboard module is missing ${snippet}`);
|
||||
@@ -2699,6 +2704,11 @@ for (const snippet of [
|
||||
'desktop_notification_permission_action',
|
||||
'notification_permission_unavailable_response',
|
||||
'notification_delivery_unavailable_response',
|
||||
'log_desktop_notification_failure',
|
||||
'desktop notification failed for {label}: {error}',
|
||||
'log_desktop_notification_failure("permission.state", &error.to_string())',
|
||||
'log_desktop_notification_failure("permission.request", &error.to_string())',
|
||||
'log_desktop_notification_failure("delivery.show", &error.to_string())',
|
||||
'PermissionState::Granted',
|
||||
'PermissionState::Denied',
|
||||
'PermissionState::Prompt | PermissionState::PromptWithRationale',
|
||||
@@ -2707,6 +2717,7 @@ for (const snippet of [
|
||||
'local_notification_payload_truncates_to_shared_contract_limits',
|
||||
'notification_permission_unavailable_response_is_stable',
|
||||
'notification_delivery_unavailable_response_is_stable',
|
||||
'notification_failures_are_logged_without_exposing_native_detail',
|
||||
'"a".repeat(HOST_BRIDGE_LOCAL_NOTIFICATION_TITLE_MAX_LENGTH)',
|
||||
'"b".repeat(HOST_BRIDGE_LOCAL_NOTIFICATION_BODY_MAX_LENGTH)',
|
||||
'"notification permission unavailable"',
|
||||
|
||||
@@ -27,6 +27,14 @@ pub(crate) fn read_desktop_clipboard_text(app: &tauri::AppHandle) -> Result<Stri
|
||||
.map_err(|error| error.to_string())
|
||||
}
|
||||
|
||||
fn log_desktop_clipboard_failure(label: &str, error: &str) -> bool {
|
||||
if !error.is_empty() {
|
||||
eprintln!("desktop clipboard failed for {label}: {error}");
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn clipboard_write_unavailable_response(
|
||||
request: &HostBridgeRequest,
|
||||
) -> HostBridgeResponse {
|
||||
@@ -58,7 +66,10 @@ pub(crate) fn write_desktop_host_bridge_clipboard_text(
|
||||
|
||||
match write_desktop_clipboard_text(app, text) {
|
||||
Ok(()) => ok(request.id.clone(), json!(true)),
|
||||
Err(_) => clipboard_write_unavailable_response(request),
|
||||
Err(error) => {
|
||||
log_desktop_clipboard_failure("write.text", &error);
|
||||
clipboard_write_unavailable_response(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +84,10 @@ pub(crate) fn read_desktop_host_bridge_clipboard_text(
|
||||
"text": text,
|
||||
}),
|
||||
),
|
||||
Err(_) => clipboard_read_unavailable_response(request),
|
||||
Err(error) => {
|
||||
log_desktop_clipboard_failure("read.text", &error);
|
||||
clipboard_read_unavailable_response(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,4 +154,16 @@ mod tests {
|
||||
assert_eq!(read_error.code, "host_error");
|
||||
assert_eq!(read_error.message, "clipboard read unavailable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clipboard_failures_are_logged_without_exposing_native_detail() {
|
||||
assert!(!log_desktop_clipboard_failure(
|
||||
"write.text",
|
||||
"private clipboard detail"
|
||||
));
|
||||
assert!(!log_desktop_clipboard_failure(
|
||||
"read.text",
|
||||
"private clipboard detail"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,14 @@ fn notification_delivery_unavailable_response(request: &HostBridgeRequest) -> Ho
|
||||
)
|
||||
}
|
||||
|
||||
fn log_desktop_notification_failure(label: &str, error: &str) -> bool {
|
||||
if !error.is_empty() {
|
||||
eprintln!("desktop notification failed for {label}: {error}");
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
|
||||
pub(crate) fn show_desktop_local_notification(
|
||||
app: &tauri::AppHandle,
|
||||
request: &HostBridgeRequest,
|
||||
@@ -116,7 +124,10 @@ pub(crate) fn show_desktop_local_notification(
|
||||
let notification_manager = app.notification();
|
||||
let permission_state = notification_manager
|
||||
.permission_state()
|
||||
.map_err(|_| notification_permission_unavailable_response(request));
|
||||
.map_err(|error| {
|
||||
log_desktop_notification_failure("permission.state", &error.to_string());
|
||||
notification_permission_unavailable_response(request)
|
||||
});
|
||||
let permission_state = match permission_state {
|
||||
Ok(permission_state) => permission_state,
|
||||
Err(response) => return response,
|
||||
@@ -125,7 +136,10 @@ pub(crate) fn show_desktop_local_notification(
|
||||
if permission_action == DesktopNotificationPermissionAction::Request {
|
||||
let requested_state = notification_manager
|
||||
.request_permission()
|
||||
.map_err(|_| notification_permission_unavailable_response(request));
|
||||
.map_err(|error| {
|
||||
log_desktop_notification_failure("permission.request", &error.to_string());
|
||||
notification_permission_unavailable_response(request)
|
||||
});
|
||||
let requested_state = match requested_state {
|
||||
Ok(requested_state) => requested_state,
|
||||
Err(response) => return response,
|
||||
@@ -150,7 +164,10 @@ pub(crate) fn show_desktop_local_notification(
|
||||
request.id.clone(),
|
||||
desktop_notification_delivered_to_system_result(),
|
||||
),
|
||||
Err(_) => notification_delivery_unavailable_response(request),
|
||||
Err(error) => {
|
||||
log_desktop_notification_failure("delivery.show", &error.to_string());
|
||||
notification_delivery_unavailable_response(request)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,6 +236,22 @@ mod tests {
|
||||
assert_eq!(error.message, "notification delivery unavailable");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn notification_failures_are_logged_without_exposing_native_detail() {
|
||||
assert!(!log_desktop_notification_failure(
|
||||
"permission.state",
|
||||
"private notification detail"
|
||||
));
|
||||
assert!(!log_desktop_notification_failure(
|
||||
"permission.request",
|
||||
"private notification detail"
|
||||
));
|
||||
assert!(!log_desktop_notification_failure(
|
||||
"delivery.show",
|
||||
"private notification detail"
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_notification_payload_rejects_empty_and_control_text() {
|
||||
let mut empty = request("notification.showLocal");
|
||||
|
||||
Reference in New Issue
Block a user