server down handling

This commit is contained in:
2026-01-03 01:15:43 +08:00
parent ce2e0aca4f
commit 105254a817
7 changed files with 187 additions and 47 deletions

View File

@@ -1,5 +1,6 @@
use reqwest::{Client, Error};
use reqwest::{Client, StatusCode};
use serde::{Deserialize, Serialize};
use thiserror::Error;
use ts_rs::TS;
use crate::{lock_r, state::FDOLL};
@@ -14,34 +15,66 @@ pub struct HealthResponseDto {
pub db: String,
}
#[derive(Error, Debug)]
pub enum HealthError {
#[error("app configuration missing {0}")]
ConfigMissing(&'static str),
#[error("health request failed: {0}")]
Request(reqwest::Error),
#[error("unexpected health status: {0}")]
UnexpectedStatus(StatusCode),
#[error("health status reported not OK: {0}")]
NonOkStatus(String),
#[error("health response decode failed: {0}")]
Decode(reqwest::Error),
}
pub struct HealthRemote {
pub base_url: String,
pub client: Client,
}
impl HealthRemote {
pub fn new() -> Self {
pub fn try_new() -> Result<Self, HealthError> {
let guard = lock_r!(FDOLL);
Self {
base_url: guard
.app_config
.api_base_url
.as_ref()
.expect("App configuration error")
.clone(),
client: guard
.clients
.as_ref()
.expect("App configuration error")
.http_client
.clone(),
}
let base_url = guard
.app_config
.api_base_url
.as_ref()
.cloned()
.ok_or(HealthError::ConfigMissing("api_base_url"))?;
let client = guard
.clients
.as_ref()
.map(|c| c.http_client.clone())
.ok_or(HealthError::ConfigMissing("http_client"))?;
Ok(Self { base_url, client })
}
pub async fn get_health(&self) -> Result<HealthResponseDto, Error> {
pub async fn get_health(&self) -> Result<HealthResponseDto, HealthError> {
let url = format!("{}/health", self.base_url);
let resp = self.client.get(url).send().await?;
let health = resp.json().await?;
let resp = self
.client
.get(url)
.send()
.await
.map_err(HealthError::Request)?;
let resp = resp.error_for_status().map_err(|err| {
err.status()
.map(HealthError::UnexpectedStatus)
.unwrap_or_else(|| HealthError::Request(err))
})?;
let health: HealthResponseDto = resp.json().await.map_err(HealthError::Decode)?;
if health.status != "OK" {
return Err(HealthError::NonOkStatus(health.status));
}
Ok(health)
}
}