Browse Source

Bubble errors through to browser

master
Dylan Baker 3 years ago
parent
commit
aa67bdf685
3 changed files with 46 additions and 19 deletions
  1. 27
    19
      src/main.rs
  2. 6
    0
      templates/error.html
  3. 13
    0
      templates/layout.html

+ 27
- 19
src/main.rs View File

@@ -28,17 +28,9 @@ impl Post {
28 28
         let mut path: PathBuf = get_posts_directory()?;
29 29
         let filename = format!("{}.json", self.id);
30 30
         path = path.join(&filename);
31
-        let mut file = match File::create(&path) {
32
-            Err(why) => panic!("couldn't create {}: {}", self.id, why),
33
-            Ok(file) => file,
34
-        };
35
-        match file.write_all(serde_json::to_string(&self)?.as_bytes()) {
36
-            Err(why) => Err(Error::new(
37
-                ErrorKind::Other,
38
-                format!("couldn't write to {}.json: {}", self.id, why),
39
-            )),
40
-            Ok(_) => Ok(()),
41
-        }
31
+        let mut file = File::create(&path)?;
32
+        file.write_all(serde_json::to_string(&self)?.as_bytes())?;
33
+        Ok(())
42 34
     }
43 35
 }
44 36
 
@@ -53,14 +45,28 @@ fn get_posts_directory() -> Result<PathBuf, Error> {
53 45
 }
54 46
 
55 47
 async fn read_all_posts() -> Result<Vec<Post>, Error> {
56
-    let path = get_posts_directory()?;
48
+    let path = match get_posts_directory() {
49
+        Ok(p) => Ok(p),
50
+        Err(_) => Err(Error::new(ErrorKind::Other, "POSTS_DIR variable is not set"))
51
+    }?;
57 52
     let mut posts: Vec<Post> = vec![];
58 53
 
59
-    for file in read_dir(path)? {
54
+    let files = match read_dir(path) {
55
+        Ok(f) => Ok(f),
56
+        Err(_) => Err(Error::new(ErrorKind::Other, "Posts directory does not exist"))
57
+    }?;
58
+
59
+    for file in files {
60 60
         let file = file?;
61 61
         if let Some("json") = file.path().extension().and_then(OsStr::to_str) {
62
-            let contents = read_to_string(file.path()).await?;
63
-            let mut post: Post = serde_json::from_str(&contents)?;
62
+            let contents = match read_to_string(file.path()).await {
63
+                Ok(c) => Ok(c),
64
+                Err(_) => Err(Error::new(ErrorKind::Other, format!("Error reading post {:?}", file.path())))
65
+            }?;
66
+            let mut post: Post = match serde_json::from_str(&contents) {
67
+                Ok(p) => Ok(p),
68
+                Err(_) => Err(Error::new(ErrorKind::Other, format!("Error deserializing post")))
69
+            }?;
64 70
             post.body = post.body.replace("\n", "<br>");
65 71
             posts.push(post);
66 72
         }
@@ -77,10 +83,12 @@ async fn main() -> std::io::Result<()> {
77 83
 
78 84
     app.with(After(|mut res: Response| async {
79 85
         if let Some(err) = res.downcast_error::<async_std::io::Error>() {
80
-            println!("{:?}", res);
81
-            if let ErrorKind::NotFound = err.kind() {
82
-                res.set_status(StatusCode::NotFound);
83
-            }
86
+            let tera = Tera::new("templates/**/*.html")?;
87
+            let mut context = Context::new();
88
+            context.insert("error", &err.to_string());
89
+            let html = tera.render("error.html", &context)?;
90
+            res.set_body(html);
91
+            res.set_status(StatusCode::InternalServerError);
84 92
         }
85 93
 
86 94
         Ok(res)

+ 6
- 0
templates/error.html View File

@@ -0,0 +1,6 @@
1
+{% extends "layout.html" %} {% block content %}
2
+<div class="error">
3
+  <h1 class="error__heading">Error:</h1>
4
+  <p class="error__message">{{ error }}</p>
5
+</div>
6
+{% endblock %}

+ 13
- 0
templates/layout.html View File

@@ -72,6 +72,19 @@
72 72
         font-weight: normal;
73 73
       }
74 74
 
75
+      .error {
76
+        color: #942626;
77
+        text-align: center;
78
+      }
79
+
80
+      .error__heading {
81
+        margin: 2em 0 1em;
82
+      }
83
+
84
+      .error__message {
85
+        font-size: 18px;
86
+      }
87
+
75 88
       @media (max-width: 500px) {
76 89
         .form__button {
77 90
           width: 100%;

Loading…
Cancel
Save