chiark / gitweb /
Add a text::ErrorLogEntry type to format errors.
authorSimon Tatham <anakin@pobox.com>
Fri, 26 Jan 2024 07:40:01 +0000 (07:40 +0000)
committerSimon Tatham <anakin@pobox.com>
Sat, 27 Jan 2024 09:01:27 +0000 (09:01 +0000)
This works towards implementing the TUI Error Log instead of panicking
or terminating with a deliberate error message.

src/text.rs

index 7b280331baa682e3f0eddb6b2aea34bd3ef013a3..be1ab9ec66a3d92b41b7e84c266d53343470f5e2 100644 (file)
@@ -3335,3 +3335,131 @@ impl TextFragment for InstanceRulesDisplay {
         lines
     }
 }
+
+pub struct ErrorLogEntry {
+    sep: SeparatorLine,
+    title: Paragraph,
+    paras: Vec<Paragraph>,
+    blank: BlankLine,
+}
+
+impl ErrorLogEntry {
+    pub fn new(err: ClientError, date: DateTime<Utc>) -> Self {
+        let sep = SeparatorLine::new(Some(date), false, false);
+        let blank = BlankLine::new();
+        let mut paras = Vec::new();
+        let mut title = Paragraph::new().add(ColouredString::plain("Type: "));
+
+        fn log_msg(paras: &mut Vec<Paragraph>, msg: String) {
+            paras.push(Paragraph::new().add(ColouredString::plain(&msg)));
+        }
+        fn log_status(
+            paras: &mut Vec<Paragraph>,
+            status: reqwest::StatusCode,
+        ) {
+            paras.push(Paragraph::new().add(ColouredString::plain(&format!(
+                "HTTP status: {}",
+                status.to_string()
+            ))))
+        }
+        fn log_url(paras: &mut Vec<Paragraph>, url: String) {
+            paras.push(
+                Paragraph::new()
+                    .add(ColouredString::plain("while fetching URL: "))
+                    .add(ColouredString::uniform(&url, 'u')),
+            )
+        }
+
+        match err {
+            ClientError::Internal(msg) => {
+                title.push_text(
+                    ColouredString::uniform("internal error", 'r'),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+            }
+            ClientError::UrlParse(url, msg) => {
+                title.push_text(
+                    ColouredString::plain("URL parsing error"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+                log_url(&mut paras, url);
+            }
+            ClientError::UrlFetchNet(url, msg) => {
+                title.push_text(ColouredString::plain("network error"), false);
+                log_msg(&mut paras, msg);
+                log_url(&mut paras, url);
+            }
+            ClientError::UrlFetchHTTP(url, status) => {
+                title.push_text(ColouredString::plain("HTTP error"), false);
+                log_status(&mut paras, status);
+                log_url(&mut paras, url);
+            }
+            ClientError::UrlFetchHTTPRich(url, status, msg) => {
+                title.push_text(
+                    ColouredString::plain("error from Mastodon server"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+                log_status(&mut paras, status);
+                log_url(&mut paras, url);
+            }
+            ClientError::JSONParse(url, msg) => {
+                title.push_text(
+                    ColouredString::plain("JSON parsing error"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+                log_url(&mut paras, url);
+            }
+            ClientError::LinkParse(url, msg) => {
+                title.push_text(
+                    ColouredString::plain("Link header parsing error"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+                log_url(&mut paras, url);
+            }
+            ClientError::UrlConsistency(url, msg) => {
+                title.push_text(
+                    ColouredString::plain("server data consistency error"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+                log_url(&mut paras, url);
+            }
+            ClientError::Consistency(msg) => {
+                title.push_text(
+                    ColouredString::plain("server data consistency error"),
+                    false,
+                );
+                log_msg(&mut paras, msg);
+            }
+        }
+
+        ErrorLogEntry {
+            sep,
+            title,
+            paras,
+            blank,
+        }
+    }
+}
+
+impl TextFragment for ErrorLogEntry {
+    fn render_highlighted(
+        &self,
+        width: usize,
+        _highlight: Option<Highlight>,
+        _style: &dyn DisplayStyleGetter,
+    ) -> Vec<ColouredString> {
+        let mut lines = Vec::new();
+        push_fragment(&mut lines, self.sep.render(width));
+        push_fragment(&mut lines, self.title.render(width));
+        push_fragment(&mut lines, self.blank.render(width));
+        push_fragment(&mut lines, self.paras.render(width));
+        push_fragment(&mut lines, self.blank.render(width));
+        lines
+    }
+}