diff --git a/src/routes/blogs.rs b/src/routes/blogs.rs index ecd01394..eecc07fc 100644 --- a/src/routes/blogs.rs +++ b/src/routes/blogs.rs @@ -19,14 +19,16 @@ use utils; #[get("/~/", rank = 2)] fn details(name: String, conn: DbConn, user: Option) -> Template { - let blog = Blog::find_by_fqn(&*conn, name).unwrap(); - let recents = Post::get_recents_for_blog(&*conn, &blog, 5); - Template::render("blogs/details", json!({ - "blog": blog, - "account": user, - "is_author": user.map(|x| x.is_author_in(&*conn, blog)), - "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::>() - })) + may_fail!(Blog::find_by_fqn(&*conn, name), "Requested blog couldn't be found", |blog| { + let recents = Post::get_recents_for_blog(&*conn, &blog, 5); + + Template::render("blogs/details", json!({ + "blog": blog, + "account": user, + "is_author": user.map(|x| x.is_author_in(&*conn, blog)), + "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::>() + })) + }) } #[get("/~/", format = "application/activity+json", rank = 1)] diff --git a/src/routes/comments.rs b/src/routes/comments.rs index 56cbb805..289dee28 100644 --- a/src/routes/comments.rs +++ b/src/routes/comments.rs @@ -17,11 +17,12 @@ use safe_string::SafeString; #[get("/~/<_blog>//comment")] fn new(_blog: String, slug: String, user: User, conn: DbConn) -> Template { - let post = Post::find_by_slug(&*conn, slug).unwrap(); - Template::render("comments/new", json!({ - "post": post, - "account": user - })) + may_fail!(Post::find_by_slug(&*conn, slug), "Couldn't find this post", |post| { + Template::render("comments/new", json!({ + "post": post, + "account": user + })) + }) } #[get("/~///comment", rank=2)] diff --git a/src/routes/mod.rs b/src/routes/mod.rs index 4787b4d2..89ab2c00 100644 --- a/src/routes/mod.rs +++ b/src/routes/mod.rs @@ -1,6 +1,32 @@ use rocket::response::NamedFile; use std::path::{Path, PathBuf}; +macro_rules! may_fail { + ($expr:expr, $template:expr, $msg:expr, | $res:ident | $block:block) => { + { + let res = $expr; + if res.is_some() { + let $res = res.unwrap(); + $block + } else { + Template::render(concat!("errors/", stringify!($template)), json!({ + "error_message": $msg + })) + } + } + }; + ($expr:expr, $msg:expr, | $res:ident | $block:block) => { + may_fail!($expr, "404", $msg, |$res| { + $block + }) + }; + ($expr:expr, | $res:ident | $block:block) => { + may_fail!($expr, "", |$res| { + $block + }) + }; +} + pub mod blogs; pub mod comments; pub mod errors; diff --git a/src/routes/posts.rs b/src/routes/posts.rs index c0b7663b..4fd02666 100644 --- a/src/routes/posts.rs +++ b/src/routes/posts.rs @@ -19,22 +19,24 @@ use safe_string::SafeString; #[get("/~//", rank = 4)] fn details(blog: String, slug: String, conn: DbConn, user: Option) -> Template { - let blog = Blog::find_by_fqn(&*conn, blog).unwrap(); - let post = Post::find_by_slug(&*conn, slug).unwrap(); - let comments = Comment::find_by_post(&*conn, post.id); + may_fail!(Blog::find_by_fqn(&*conn, blog), "Couldn't find this blog", |blog| { + may_fail!(Post::find_by_slug(&*conn, slug), "Couldn't find this post", |post| { + let comments = Comment::find_by_post(&*conn, post.id); - Template::render("posts/details", json!({ - "author": post.get_authors(&*conn)[0].to_json(&*conn), - "post": post, - "blog": blog, - "comments": comments.into_iter().map(|c| c.to_json(&*conn)).collect::>(), - "n_likes": post.get_likes(&*conn).len(), - "has_liked": user.clone().map(|u| u.has_liked(&*conn, &post)).unwrap_or(false), - "n_reshares": post.get_reshares(&*conn).len(), - "has_reshared": user.clone().map(|u| u.has_reshared(&*conn, &post)).unwrap_or(false), - "account": user, - "date": &post.creation_date.timestamp() - })) + Template::render("posts/details", json!({ + "author": post.get_authors(&*conn)[0].to_json(&*conn), + "post": post, + "blog": blog, + "comments": comments.into_iter().map(|c| c.to_json(&*conn)).collect::>(), + "n_likes": post.get_likes(&*conn).len(), + "has_liked": user.clone().map(|u| u.has_liked(&*conn, &post)).unwrap_or(false), + "n_reshares": post.get_reshares(&*conn).len(), + "has_reshared": user.clone().map(|u| u.has_reshared(&*conn, &post)).unwrap_or(false), + "account": user, + "date": &post.creation_date.timestamp() + })) + }) + }) } #[get("/~/<_blog>/", rank = 3, format = "application/activity+json")] diff --git a/src/routes/user.rs b/src/routes/user.rs index d485df1e..6b925c87 100644 --- a/src/routes/user.rs +++ b/src/routes/user.rs @@ -25,7 +25,7 @@ use models::{ use utils; #[get("/me")] -fn me(user: Option) -> Result> { +fn me(user: Option) -> Result> { match user { Some(user) => Ok(Redirect::to(format!("/@/{}/", user.username))), None => Err(utils::requires_login("", "/me")) @@ -34,23 +34,24 @@ fn me(user: Option) -> Result> { #[get("/@/", rank = 2)] fn details(name: String, conn: DbConn, account: Option) -> Template { - let user = User::find_by_fqn(&*conn, name).unwrap(); - let recents = Post::get_recents_for_author(&*conn, &user, 6); - let reshares = Reshare::get_recents_for_author(&*conn, &user, 6); - let user_id = user.id.clone(); - let n_followers = user.get_followers(&*conn).len(); + may_fail!(User::find_by_fqn(&*conn, name), "Couldn't find requested user", |user| { + let recents = Post::get_recents_for_author(&*conn, &user, 6); + let reshares = Reshare::get_recents_for_author(&*conn, &user, 6); + let user_id = user.id.clone(); + let n_followers = user.get_followers(&*conn).len(); - Template::render("users/details", json!({ - "user": serde_json::to_value(user.clone()).unwrap(), - "instance_url": user.get_instance(&*conn).public_domain, - "is_remote": user.instance_id != Instance::local_id(&*conn), - "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), - "account": account, - "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::>(), - "reshares": reshares.into_iter().map(|r| r.get_post(&*conn).unwrap().to_json(&*conn)).collect::>(), - "is_self": account.map(|a| a.id == user_id).unwrap_or(false), - "n_followers": n_followers - })) + Template::render("users/details", json!({ + "user": serde_json::to_value(user.clone()).unwrap(), + "instance_url": user.get_instance(&*conn).public_domain, + "is_remote": user.instance_id != Instance::local_id(&*conn), + "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), + "account": account, + "recents": recents.into_iter().map(|p| p.to_json(&*conn)).collect::>(), + "reshares": reshares.into_iter().map(|r| r.get_post(&*conn).unwrap().to_json(&*conn)).collect::>(), + "is_self": account.map(|a| a.id == user_id).unwrap_or(false), + "n_followers": n_followers + })) + }) } #[get("/dashboard")] @@ -91,19 +92,20 @@ fn follow_auth(name: String) -> Flash { #[get("/@//followers", rank = 2)] fn followers(name: String, conn: DbConn, account: Option) -> Template { - let user = User::find_by_fqn(&*conn, name.clone()).unwrap(); - let user_id = user.id.clone(); + may_fail!(User::find_by_fqn(&*conn, name.clone()), "Couldn't find requested user", |user| { + let user_id = user.id.clone(); - Template::render("users/followers", json!({ - "user": serde_json::to_value(user.clone()).unwrap(), - "instance_url": user.get_instance(&*conn).public_domain, - "is_remote": user.instance_id != Instance::local_id(&*conn), - "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), - "followers": user.get_followers(&*conn).into_iter().map(|f| f.to_json(&*conn)).collect::>(), - "account": account, - "is_self": account.map(|a| a.id == user_id).unwrap_or(false), - "n_followers": user.get_followers(&*conn).len() - })) + Template::render("users/followers", json!({ + "user": serde_json::to_value(user.clone()).unwrap(), + "instance_url": user.get_instance(&*conn).public_domain, + "is_remote": user.instance_id != Instance::local_id(&*conn), + "follows": account.clone().map(|x| x.is_following(&*conn, user.id)).unwrap_or(false), + "followers": user.get_followers(&*conn).into_iter().map(|f| f.to_json(&*conn)).collect::>(), + "account": account, + "is_self": account.map(|a| a.id == user_id).unwrap_or(false), + "n_followers": user.get_followers(&*conn).len() + })) + }) } #[get("/@/", format = "application/activity+json", rank = 1)]