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
- 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.
- Create a custom error enum — Replace
Result<T, String> with Result<T, VeskforgeError> that implements std::fmt::Display and logs on creation.
- Log plugin lifecycle events — Install, uninstall, enable, disable, update. Include plugin ID, source, and outcome. This creates an audit trail for user support.
- 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.
- 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) |
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 withformat!()messages. The TypeScript frontend has zeroconsole.*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
log,tracing,slog, orenv_loggerdependency insrc-tauri/Cargo.tomlconsole.log/warn/error/info/debugcalls in any.ts/.tsxfile.unwrap()calls inlib.rs— all in test code, but no error logging in production paths.map_err()/?operators — all errors are converted toStringviaformat!()and returned to the Tauri frontend with no logging side-effect🔴 HIGH: All errors are stringly-typed — no structured error reporting
Result<T, String>— no custom error enum#[tauri::command]functions all returnResult<_, String>🟡 MEDIUM: Plugin operations have no audit trail
lib.rs~lines 1100-1200): git clone, file copy, manifest write — all silent on success/failurelib.rs~lines 1248-1430): install, uninstall, list, update — no logging of which plugins were modifiedlogfield in some structs (lines 765, 822, 1426, 1524) — these are data fields (build/install logs shown to users), not diagnostic logging🟡 MEDIUM: Filesystem operations have no diagnostic output
app_data_dir(),workspace_dir(),managed_plugins_dir()— all create directories silentlyread_manifest(),write_manifest()— no logging of manifest state changesvalidate_local_plugin_path,validate_plugin_entrypoint_content) — validation failures only surface as error strings🟢 LOW: Frontend error handling is invisible
invoke()from Tauri API — errors from Rust surface as rejected promisesApp.tsxRecommendations
tracingwithtracing-subscriberto Rust backend — Usetracing::info!for plugin operations,tracing::warn!for validation failures,tracing::error!for filesystem/API errors.Result<T, String>withResult<T, VeskforgeError>that implementsstd::fmt::Displayand logs on creation.console.errorcatches in invoke wrappers would help. Consider a Tauri event for sending Rust logs to the frontend devtools.app_data_dir()/veskforge.logso users can share logs for bug reports.Stats
lib.rs,main.rs,build.rs)App.tsx,main.tsx,vite-env.d.ts)eprintln!/println!callsconsole.*calls.unwrap()calls#[cfg(test)]).map_err()/?operators#[tauri::command]functionsString(no structured error enum)