Backend: - migrations/003_jobs_scheduling.sql: retry_next_at/last_error columns, pg_notify trigger for immediate job dispatch, retry index - pm-agent-client: ApplyPatchesRequest/Response, AgentJobStatus, RollbackResponse types; apply_patches/job_status/rollback_job client methods + generic POST helper - pm-core/models: JobStatus, JobKind, PatchJob, PatchJobHost, CreateJobRequest, PatchJobSummary - pm-web/routes/jobs.rs: POST/GET /api/v1/jobs, GET /jobs/:id, POST /jobs/:id/cancel, POST /jobs/:id/rollback - pm-worker/job_executor.rs: NOTIFY listener, periodic scanner, execute_host_job, poll_running_jobs, handle_host_failure (3-retry exponential backoff 1m/5m/30m), sync_job_status, retry_pending_jobs - pm-worker/main.rs: spawn job_executor Frontend: - types/index.ts: PatchInfo, PatchJobHost, PatchJob, PatchJobSummary, CreateJobRequest interfaces - api/client.ts: jobsApi (list/get/create/cancel/rollback), patchesApi (getHostPatches) - pages/PatchDeploymentPage.tsx: 3-step MUI Stepper (host select → configure → result) - pages/JobsPage.tsx: job list table, expandable per-host detail, cancel/rollback actions with confirm dialog, load-more pagination - App.tsx: /jobs and /deployment routes wired to real pages cargo check: 0 errors | vite build: 0 errors
50 lines
1.5 KiB
Rust
50 lines
1.5 KiB
Rust
//! Error types for the pm-agent-client crate.
|
|
|
|
use thiserror::Error;
|
|
|
|
/// Top-level error type returned by [`crate::client::AgentClient`] methods.
|
|
#[derive(Debug, Error)]
|
|
pub enum AgentClientError {
|
|
/// TLS configuration or handshake failure.
|
|
#[error("TLS error: {0}")]
|
|
Tls(String),
|
|
|
|
/// Unable to establish a TCP/TLS connection to the agent.
|
|
#[error("Connection error: {0}")]
|
|
Connect(#[source] reqwest::Error),
|
|
|
|
/// An HTTP request or response transport error (not a timeout).
|
|
#[error("Request error: {0}")]
|
|
Request(#[source] reqwest::Error),
|
|
|
|
/// The request did not complete within the configured timeout.
|
|
#[error("Request timed out")]
|
|
Timeout,
|
|
|
|
/// The agent returned a non-2xx HTTP status or `success: false` in the
|
|
/// response envelope.
|
|
#[error("Agent API error [{code}]: {message}")]
|
|
ApiError {
|
|
/// Machine-readable error code supplied by the agent (e.g. `"NOT_FOUND"`).
|
|
code: String,
|
|
/// Human-readable description returned by the agent.
|
|
message: String,
|
|
},
|
|
|
|
/// JSON deserialization of the agent response failed.
|
|
#[error("Failed to deserialise agent response: {0}")]
|
|
Deserialize(#[from] serde_json::Error),
|
|
}
|
|
|
|
impl From<reqwest::Error> for AgentClientError {
|
|
fn from(err: reqwest::Error) -> Self {
|
|
if err.is_timeout() {
|
|
AgentClientError::Timeout
|
|
} else if err.is_connect() {
|
|
AgentClientError::Connect(err)
|
|
} else {
|
|
AgentClientError::Request(err)
|
|
}
|
|
}
|
|
}
|