{"record":{"id":"8bed8c11e5336ad1","repo":"jlcodes99/cockpit-tools","slug":"updater","errorCode":null,"errorMessage":"[Updater] {}","messagePattern":"\\[Updater\\] (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"src-tauri/src/commands/update.rs","lineNumber":145,"sourceCode":"pub fn get_release_history(\n    locale: Option<String>,\n    limit: Option<usize>,\n) -> Result<Vec<ReleaseHistoryItem>, String> {\n    update_checker::get_release_history(locale.as_deref(), limit)\n}\n\n/// Write updater lifecycle logs from frontend into app.log\n#[tauri::command]\npub fn update_log(level: String, message: String) -> Result<(), String> {\n    let level = level.trim().to_lowercase();\n    let message = message.trim();\n    if message.is_empty() {\n        return Ok(());\n    }\n\n    let text = format!(\"[Updater] {}\", message);\n    match level.as_str() {\n        \"error\" => logger::log_error(&text),\n        \"warn\" | \"warning\" => logger::log_warn(&text),\n        _ => logger::log_info(&text),\n    }\n\n    Ok(())\n}\n\n#[tauri::command]\npub fn get_update_runtime_info() -> Result<UpdateRuntimeInfo, String> {\n    Ok(linux_updater::get_update_runtime_info())\n}\n\n#[tauri::command]\npub async fn install_linux_update(\n    app: tauri::AppHandle,\n    expected_version: Option<String>,\n) -> Result<(), String> {\n    linux_updater::install_linux_update(app, expected_version).await","sourceCodeStart":127,"sourceCodeEnd":163,"githubUrl":"https://github.com/jlcodes99/cockpit-tools/blob/1ed8b77992d62ca81fabf744deb0839ad361d5bf/src-tauri/src/commands/update.rs#L127-L163","documentation":"The update_log command receives a log message and level from the frontend, prefixes it with '[Updater] ', and routes it to the appropriate logger (log_error/log_warn/log_info); it returns Ok(()) unless the message is empty (early return). The shown message '[Updater] {}' is the format template of every frontend-relayed updater log line, not a thrown error itself.","triggerScenarios":"Any frontend code invoking the update_log Tauri command with level 'error' produces this error-tagged line; the underlying updater failure text is whatever the frontend passed in `message`.","commonSituations":"Frontend updater flow reporting download/install/check failures; empty messages are silently ignored (early return Ok), so nothing is thrown here.","solutions":["Look at the text after '[Updater] ' for the real frontend-reported updater failure.","Check frontend updater code that calls invoke('update_log', ...) to see the originating condition.","If logs are missing entirely, verify the frontend passes a non-empty message, since empty messages are dropped.","Match the level string exactly ('error', 'warn'/'warning') — other values are demoted to info logs."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Frontend: validate before invoking update_log\nfunction safeUpdateLog(message: string, level: string) {\n  if (!message.trim()) return; // empty messages are dropped by the backend anyway\n  return invoke('update_log', { message, level: ['error','warn','warning'].includes(level) ? level : 'info' });\n}","typeGuard":"function isLogLevel(l: unknown): l is 'error' | 'warn' | 'warning' | 'info' {\n  return typeof l === 'string' && ['error','warn','warning','info'].includes(l);\n}","tryCatchPattern":"try {\n  await safeUpdateLog(msg, level);\n} catch (e) {\n  console.error('[Updater] failed to relay log to backend', e); // logging must never break the updater\n}","preventionTips":["Never let log relay failures break the updater flow","Pass explicit level strings matching backend expectations","Keep messages non-empty and bounded in size","Use structured payloads instead of free-form strings when possible"],"tags":["updater","logging","tauri","frontend"],"backgroundTag":"updater-log-relay","analyzedSha":"1ed8b77992d62ca81fabf744deb0839ad361d5bf","analyzedAt":"2026-09-05T09:51:41.178Z","contentChangedAt":"2026-09-05T09:51:41.178Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}