P1: sidecar lifecycle and HTTP bridge
Backend - sidecar.rs supervises the bundled `mycelium` binary launched via pkexec; locates it in resource_dir or CARGO_MANIFEST_DIR/binaries matching $TAURI_ENV_TARGET_TRIPLE - ephemeral port via portpicker, key + config persisted in app_data_dir, kill_on_drop with explicit start_kill on stop - health-check loop calls /api/v1/admin until 2xx (timeout 20s); emits sidecar://ready and sidecar://exited - 500-line ring buffer of stdout/stderr surfaced via sidecar_logs command for the upcoming Settings page - elevation::is_auth_failure(126|127) maps pkexec cancel to a dedicated AppError variant - AppError uses thiserror, Serialize impl renders messages as plain strings for the JS side Frontend - typed `api` wrapper around invoke() in src/lib/api.ts - node store (Pinia) bootstraps on mount, listens on sidecar://ready and sidecar://exited - StartupOverlay covers the whole window for idle/starting/error phases; sidebar status dot + start/stop button - Status view renders subnet, pubkey, api endpoint and key path with one-click clipboard copy
This commit is contained in:
54
src-tauri/src/error.rs
Normal file
54
src-tauri/src/error.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum AppError {
|
||||
#[error("daemon not running")]
|
||||
DaemonNotRunning,
|
||||
|
||||
#[error("daemon already running")]
|
||||
DaemonAlreadyRunning,
|
||||
|
||||
#[error("daemon health-check timed out after {0}s")]
|
||||
HealthCheckTimeout(u64),
|
||||
|
||||
#[error("could not locate mycelium sidecar binary (looked for {0:?})")]
|
||||
SidecarNotFound(Vec<std::path::PathBuf>),
|
||||
|
||||
#[error("sidecar exited unexpectedly: {0}")]
|
||||
SidecarExited(String),
|
||||
|
||||
#[error("pkexec authentication was cancelled or failed")]
|
||||
ElevationCancelled,
|
||||
|
||||
#[error("io error: {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
|
||||
#[error("http error: {0}")]
|
||||
Http(#[from] reqwest::Error),
|
||||
|
||||
#[error("daemon returned status {status}: {body}")]
|
||||
DaemonStatus { status: u16, body: String },
|
||||
|
||||
#[error("tauri error: {0}")]
|
||||
Tauri(#[from] tauri::Error),
|
||||
|
||||
#[error("tauri path error: {0}")]
|
||||
TauriPath(String),
|
||||
|
||||
#[error("invalid argument: {0}")]
|
||||
BadInput(String),
|
||||
|
||||
#[error("{0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
pub type AppResult<T> = Result<T, AppError>;
|
||||
|
||||
// Serialize errors as plain strings for the JS side. invoke() rejects with
|
||||
// the message; the front-end matches on substring or surfaces it raw.
|
||||
impl Serialize for AppError {
|
||||
fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||
s.serialize_str(&self.to_string())
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user