Radish alpha
r
Radicle CI broker
Radicle
Git (anonymous pull)
Log in to clone via SSH
refactor(src/pages.rs): handle errors without panic
Lars Wirzenius committed 1 year ago
commit 8b31157ab3adc66ec57ca1e119be0095b783e168
parent d82c077579a51fabf65932c0119cfe1a7cacff93
1 file changed +23 -17
modified src/pages.rs
@@ -37,6 +37,10 @@ const UPDATE_INTERVAL: Duration = Duration::from_secs(60);
/// All possible errors returned from the status page module.
#[derive(Debug, thiserror::Error)]
pub enum PageError {
+
    /// Error formatting a time as a string.
+
    #[error(transparent)]
+
    Timeformat(#[from] time::error::Format),
+

    #[error("failed to write status page to {0}")]
    Write(PathBuf, #[source] std::io::Error),

@@ -51,6 +55,9 @@ pub enum PageError {

    #[error("failed to lock page data structure")]
    Lock(&'static str),
+

+
    #[error("failed to represent status page data as JSON")]
+
    StatusToJson(#[source] serde_json::Error),
}

/// A builder for constructing a [`StatusPage`] value. It will only
@@ -80,7 +87,7 @@ impl PageBuilder {
        debug!("broker database has {} CI runs", runs.len());

        Ok(StatusPage::new(PageData {
-
            timestamp: now(),
+
            timestamp: now()?,
            ci_broker_version: env!("CARGO_PKG_VERSION"),
            ci_broker_git_commit: env!("GIT_HEAD"),
            node_alias: self.node_alias.ok_or(PageError::NoAlias)?,
@@ -92,9 +99,9 @@ impl PageBuilder {
    }
}

-
fn now() -> String {
+
fn now() -> Result<String, time::error::Format> {
    let fmt = format_description!("[year]-[month]-[day] [hour]:[minute]:[second]Z");
-
    OffsetDateTime::now_utc().format(fmt).ok().unwrap()
+
    OffsetDateTime::now_utc().format(fmt)
}

struct PageData {
@@ -109,7 +116,7 @@ struct PageData {
}

impl PageData {
-
    fn status_page_as_html(&self) -> Document {
+
    fn status_page_as_html(&self) -> Result<Document, PageError> {
        let mut doc = Document::default();

        doc.push_to_head(
@@ -145,7 +152,7 @@ impl PageData {
                .with_text(")"),
        );

-
        let status = StatusData::from(self).as_json();
+
        let status = StatusData::from(self).as_json()?;
        doc.push_to_body(
            Element::new(Tag::P).with_child(
                Element::new(Tag::A)
@@ -232,7 +239,7 @@ impl PageData {
        }
        doc.push_to_body(list);

-
        doc
+
        Ok(doc)
    }

    fn whence_as_html(whence: &Whence) -> Element {
@@ -474,7 +481,7 @@ impl StatusPage {

    pub fn update_timestamp(&mut self) -> Result<(), PageError> {
        let mut data = self.lock()?;
-
        data.timestamp = now();
+
        data.timestamp = now()?;
        Ok(())
    }

@@ -542,7 +549,7 @@ impl StatusPage {
        let (status, repos) = {
            let data = self.lock()?;

-
            let status = data.status_page_as_html().to_string();
+
            let status = data.status_page_as_html()?.to_string();

            let mut repos = vec![];
            for (_, rid) in data.repos() {
@@ -556,10 +563,11 @@ impl StatusPage {
            (status, repos)
        };

-
        Self::write_file(&dirname.join("index.html"), &status).unwrap();
+
        let filename = dirname.join("index.html");
+
        Self::write_file(&filename, &status)?;

        for (filename, repopage) in repos {
-
            Self::write_file(&filename, &repopage).unwrap();
+
            Self::write_file(&filename, &repopage)?;
        }

        Ok(())
@@ -571,17 +579,15 @@ impl StatusPage {
        // contention.
        let status = {
            let data = self.lock()?;
-
            StatusData::from(&*data).as_json()
+
            StatusData::from(&*data).as_json()?
        };

-
        Self::write_file(filename, &status).unwrap();
-

-
        Ok(())
+
        Self::write_file(filename, &status)
    }

    fn write_file(filename: &Path, text: &str) -> Result<(), PageError> {
        debug!("write file {}", filename.display());
-
        write(filename, text).unwrap();
+
        write(filename, text).map_err(|e| PageError::Write(filename.into(), e))?;
        Ok(())
    }
}
@@ -607,8 +613,8 @@ struct StatusData {
}

impl StatusData {
-
    fn as_json(&self) -> String {
-
        serde_json::to_string_pretty(self).unwrap()
+
    fn as_json(&self) -> Result<String, PageError> {
+
        serde_json::to_string_pretty(self).map_err(PageError::StatusToJson)
    }
}