Skip to content

nightshift: logging-audit — zero logging, stringly-typed errors, no observability in Tauri app #2

@nightshift-micr

Description

@nightshift-micr

nightshift: logging-audit — Tauri app with zero logging, stringly-typed errors, no observability

Summary

veskforge is a Tauri 2 desktop application (1,832 lines Rust backend, 958 lines TypeScript frontend) with no logging framework on either side. The Rust backend uses Result<T, String> for all errors with format!() messages. The TypeScript frontend has zero console.* calls. There is no runtime observability for debugging plugin installation failures, filesystem errors, or user-reported issues.

Findings

🔴 HIGH: No logging anywhere — Rust backend + TypeScript frontend

  • Rust: No log, tracing, slog, or env_logger dependency in src-tauri/Cargo.toml
  • TypeScript: Zero console.log/warn/error/info/debug calls in any .ts/.tsx file
  • 42 .unwrap() calls in lib.rs — all in test code, but no error logging in production paths
  • 147 .map_err() / ? operators — all errors are converted to String via format!() and returned to the Tauri frontend with no logging side-effect

🔴 HIGH: All errors are stringly-typed — no structured error reporting

  • Every function returns Result<T, String> — no custom error enum
  • 13 #[tauri::command] functions all return Result<_, String>
  • Error messages include useful context (paths, operation names) but are only visible to the user at the point of failure — not logged anywhere for post-mortem
  • No error categorization — filesystem errors, parse errors, and business logic errors all look the same

🟡 MEDIUM: Plugin operations have no audit trail

  • Plugin install (lib.rs ~lines 1100-1200): git clone, file copy, manifest write — all silent on success/failure
  • Plugin management commands (lib.rs ~lines 1248-1430): install, uninstall, list, update — no logging of which plugins were modified
  • log field in some structs (lines 765, 822, 1426, 1524) — these are data fields (build/install logs shown to users), not diagnostic logging
  • No way to answer "what happened" when a user reports a broken plugin installation

🟡 MEDIUM: Filesystem operations have no diagnostic output

  • app_data_dir(), workspace_dir(), managed_plugins_dir() — all create directories silently
  • read_manifest(), write_manifest() — no logging of manifest state changes
  • Plugin validation (validate_local_plugin_path, validate_plugin_entrypoint_content) — validation failures only surface as error strings

🟢 LOW: Frontend error handling is invisible

  • TypeScript uses invoke() from Tauri API — errors from Rust surface as rejected promises
  • No error boundary component visible in App.tsx
  • No client-side error logging for UI state issues

Recommendations

  1. Add tracing with tracing-subscriber to Rust backend — Use tracing::info! for plugin operations, tracing::warn! for validation failures, tracing::error! for filesystem/API errors.
  2. Create a custom error enum — Replace Result<T, String> with Result<T, VeskforgeError> that implements std::fmt::Display and logs on creation.
  3. Log plugin lifecycle events — Install, uninstall, enable, disable, update. Include plugin ID, source, and outcome. This creates an audit trail for user support.
  4. Add frontend error logging — Even console.error catches in invoke wrappers would help. Consider a Tauri event for sending Rust logs to the frontend devtools.
  5. Log file for user support — Write structured logs to app_data_dir()/veskforge.log so users can share logs for bug reports.

Stats

Metric Value
Rust source files 3 (lib.rs, main.rs, build.rs)
Rust lines 1,832
TypeScript files 3 (App.tsx, main.tsx, vite-env.d.ts)
TypeScript lines 958
Logging framework None (Rust + TypeScript)
eprintln!/println! calls 0 (production code)
console.* calls 0
.unwrap() calls 42 (all in #[cfg(test)])
.map_err()/? operators 147
#[tauri::command] functions 13
Files with zero logging All source files (100%)
Error type String (no structured error enum)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions