env vars: improve error messages somewhat

This commit is contained in:
Armaël Guéneau 2025-01-03 11:43:02 +01:00
parent f5c29ceffb
commit 11e4444153
4 changed files with 31 additions and 31 deletions

View file

@ -1,7 +1,7 @@
use crate::util::env_var;
use crate::Config; use crate::Config;
use anyhow::anyhow; use anyhow::anyhow;
use lettre::{Message, SmtpTransport, Transport}; use lettre::{Message, SmtpTransport, Transport};
use std::env;
pub struct SmtpConfig { pub struct SmtpConfig {
address: String, address: String,
@ -21,9 +21,9 @@ impl SmtpConfig {
} }
pub async fn from_env() -> anyhow::Result<SmtpConfig> { pub async fn from_env() -> anyhow::Result<SmtpConfig> {
let address = env::var("SMTP_ADDRESS")?; let address = env_var("SMTP_ADDRESS")?;
let username = env::var("SMTP_USERNAME")?; let username = env_var("SMTP_USERNAME")?;
let password = env::var("SMTP_PASSWORD")?; let password = env_var("SMTP_PASSWORD")?;
let smtp = SmtpConfig { let smtp = SmtpConfig {
address, address,
username, username,

View file

@ -23,6 +23,7 @@ mod email;
mod scrape; mod scrape;
mod storage; mod storage;
mod userdb; mod userdb;
mod util;
mod workers; mod workers;
use data::*; use data::*;
@ -30,6 +31,7 @@ use db::Db;
use email::SmtpConfig; use email::SmtpConfig;
use storage::Storage; use storage::Storage;
use userdb::{IsSpam, UserDb}; use userdb::{IsSpam, UserDb};
use util::env_var;
// Fetch user data from forgejo from time to time // Fetch user data from forgejo from time to time
const FORGEJO_POLL_DELAY: Duration = Duration::from_secs(11 * 3600); // 11 hours const FORGEJO_POLL_DELAY: Duration = Duration::from_secs(11 * 3600); // 11 hours
@ -63,16 +65,12 @@ pub struct Config {
impl Config { impl Config {
async fn from_env() -> anyhow::Result<Self> { async fn from_env() -> anyhow::Result<Self> {
let forge_url_s = let forge_url_s = env_var("FORGE_URL")?;
std::env::var("FORGE_URL").context("reading the FORGE_URL environment variable")?; let forge_api_token = env_var("FORGE_API_TOKEN")?;
let forge_api_token = let org_name = env_var("ORG_NAME")?;
std::env::var("FORGE_API_TOKEN").context("reading the FORGE_API_TOKEN environment variable")?; let admin_contact_email = env_var("ADMIN_CONTACT_EMAIL")?;
let org_name =
std::env::var("ORG_NAME").context("reading the ORG_NAME environment variable")?;
let admin_contact_email = std::env::var("ADMIN_CONTACT_EMAIL")
.context("reading the ADMIN_CONTACT_EMAIL environment variable")?;
let actually_ban = match std::env::var("ACTUALLY_BAN_USERS").as_deref() { let actually_ban = match env_var("ACTUALLY_BAN_USERS").as_deref() {
Ok("true") => ActuallyBan::Yes { Ok("true") => ActuallyBan::Yes {
smtp: SmtpConfig::from_env().await?, smtp: SmtpConfig::from_env().await?,
}, },
@ -85,13 +83,12 @@ impl Config {
Err(_) => ActuallyBan::No, Err(_) => ActuallyBan::No,
}; };
let listen_addr = std::env::var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0")); let listen_addr = env_var("LISTEN_ADDR").unwrap_or(String::from("0.0.0.0"));
let listen_port: u16 = let listen_port: u16 = match env_var("LISTEN_PORT").map(|s| u16::from_str_radix(&s, 10)) {
match std::env::var("LISTEN_PORT").map(|s| u16::from_str_radix(&s, 10)) { Ok(Err(e)) => return Err(anyhow!("LISTEN_PORT: invalid value ({})", e)),
Ok(Err(e)) => return Err(anyhow!("LISTEN_PORT: invalid value ({})", e)), Ok(Ok(p)) => p,
Ok(Ok(p)) => p, Err(_) => 8080,
Err(_) => 8080, };
};
Ok(Config { Ok(Config {
forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?, forge_url: Url::parse(&forge_url_s).context("parsing FORGE_URL")?,
@ -448,15 +445,12 @@ async fn get_static_(
Some(page) => { Some(page) => {
let mime = new_mime_guess::from_path(&filename).first_or_octet_stream(); let mime = new_mime_guess::from_path(&filename).first_or_octet_stream();
([(header::CONTENT_TYPE, mime.to_string())], page.contents()).into_response() ([(header::CONTENT_TYPE, mime.to_string())], page.contents()).into_response()
}, }
} }
} }
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
eprintln!("Eval templates");
let _ = *TEMPLATES;
let config = Arc::new(Config::from_env().await?); let config = Arc::new(Config::from_env().await?);
let storage = Arc::new(Storage::from_env().await?); let storage = Arc::new(Storage::from_env().await?);
let forge = Arc::new(Forgejo::new( let forge = Arc::new(Forgejo::new(
@ -464,6 +458,9 @@ async fn main() -> anyhow::Result<()> {
config.forge_url.clone(), config.forge_url.clone(),
)?); )?);
eprintln!("Eval templates");
let _ = *TEMPLATES;
eprintln!("Load users and repos"); eprintln!("Load users and repos");
let db = load_db(&storage, &forge).await?; let db = load_db(&storage, &forge).await?;

View file

@ -1,3 +1,4 @@
use crate::util::env_var;
use anyhow::Context; use anyhow::Context;
use aws_sdk_s3 as s3; use aws_sdk_s3 as s3;
use std::fs::File; use std::fs::File;
@ -26,20 +27,16 @@ impl Storage {
} }
pub async fn from_env() -> anyhow::Result<Self> { pub async fn from_env() -> anyhow::Result<Self> {
match std::env::var("STORAGE_BACKEND") match env_var("STORAGE_BACKEND")?.as_ref() {
.context("reading the STORAGE_BACKEND environment variable")?
.as_ref()
{
"local" => { "local" => {
let dir = match std::env::var("STORAGE_LOCAL_DIR") { let dir = match env_var("STORAGE_LOCAL_DIR") {
Ok(dir) => dir, Ok(dir) => dir,
Err(_) => ".".to_string(), Err(_) => ".".to_string(),
}; };
Ok(Self::from_local_dir(PathBuf::from(dir))) Ok(Self::from_local_dir(PathBuf::from(dir)))
} }
"s3" => { "s3" => {
let bucket = std::env::var("STORAGE_S3_BUCKET") let bucket = env_var("STORAGE_S3_BUCKET")?;
.context("reading the STORAGE_S3_BUCKET environment variable")?;
Ok(Self::from_s3(bucket).await) Ok(Self::from_s3(bucket).await)
} }
other => { other => {

6
src/util.rs Normal file
View file

@ -0,0 +1,6 @@
use anyhow::Context;
pub fn env_var(name: &str) -> anyhow::Result<String> {
let v = std::env::var(name).context(format!("reading the {} environment variable", name))?;
Ok(v)
}