diff --git a/src/web/builds.rs b/src/web/builds.rs index f807ee93a..c8cdf8549 100644 --- a/src/web/builds.rs +++ b/src/web/builds.rs @@ -26,7 +26,7 @@ pub(crate) struct Build { #[derive(Debug, Clone, PartialEq, Eq, Serialize)] struct BuildsPage { - metadata: Option, + metadata: MetaData, builds: Vec, build_details: Option, limits: Limits, @@ -59,11 +59,11 @@ pub fn build_list_handler(req: &mut Request) -> IronResult { builds.build_status, builds.build_time, builds.output - FROM builds - INNER JOIN releases ON releases.id = builds.rid - INNER JOIN crates ON releases.crate_id = crates.id - WHERE crates.name = $1 AND releases.version = $2 - ORDER BY id DESC", + FROM builds + INNER JOIN releases ON releases.id = builds.rid + INNER JOIN crates ON releases.crate_id = crates.id + WHERE crates.name = $1 AND releases.version = $2 + ORDER BY id DESC", &[&name, &version] ) ); @@ -111,7 +111,7 @@ pub fn build_list_handler(req: &mut Request) -> IronResult { Ok(resp) } else { BuildsPage { - metadata: MetaData::from_crate(&mut conn, &name, &version), + metadata: cexpect!(req, MetaData::from_crate(&mut conn, &name, &version)), builds, build_details, limits, diff --git a/src/web/mod.rs b/src/web/mod.rs index c81e762ee..032df84be 100644 --- a/src/web/mod.rs +++ b/src/web/mod.rs @@ -6,12 +6,20 @@ use log::{debug, info}; /// ctry! (cratesfyitry) is extremely similar to try! and itry! /// except it returns an error page response instead of plain Err. +#[macro_export] macro_rules! ctry { ($req:expr, $result:expr $(,)?) => { match $result { Ok(success) => success, Err(error) => { - ::log::error!("{}\n{:?}", error, ::backtrace::Backtrace::new()); + let request: &::iron::Request = $req; + + ::log::error!( + "called ctry!() on an `Err` value: {}\nnote: while attempting to fetch the route {:?}\n{:?}", + error, + request.url, + ::backtrace::Backtrace::new(), + ); // This is very ugly, but it makes it impossible to get a type inference error // from this macro @@ -23,7 +31,7 @@ macro_rules! ctry { status: ::iron::status::BadRequest, }; - return $crate::web::page::WebPage::into_response(error, $req); + return $crate::web::page::WebPage::into_response(error, request); } } }; @@ -36,8 +44,11 @@ macro_rules! cexpect { match $option { Some(success) => success, None => { + let request: &::iron::Request = $req; + ::log::error!( - "called cexpect!() on a `None` value\n{:?}", + "called cexpect!() on a `None` value while attempting to fetch the route {:?}\n{:?}", + request.url, ::backtrace::Backtrace::new(), ); @@ -49,7 +60,7 @@ macro_rules! cexpect { status: ::iron::status::BadRequest, }; - return $crate::web::page::WebPage::into_response(error, $req); + return $crate::web::page::WebPage::into_response(error, request); } } }; diff --git a/src/web/page/web_page.rs b/src/web/page/web_page.rs index a4bb92937..f19b759c4 100644 --- a/src/web/page/web_page.rs +++ b/src/web/page/web_page.rs @@ -1,4 +1,5 @@ use super::TemplateData; +use crate::ctry; use iron::{headers::ContentType, response::Response, status::Status, IronResult, Request}; use serde::Serialize; use std::borrow::Cow; @@ -10,6 +11,7 @@ macro_rules! impl_webpage { ($page:ty = $template:literal $(, status = $status:expr)? $(, content_type = $content_type:expr)? $(,)?) => { impl_webpage!($page = |_| ::std::borrow::Cow::Borrowed($template) $(, status = $status)? $(, content_type = $content_type)?); }; + ($page:ty = $template:expr $(, status = $status:expr)? $(, content_type = $content_type:expr)? $(,)?) => { impl $crate::web::page::WebPage for $page { fn template(&self) -> ::std::borrow::Cow<'static, str> { @@ -39,14 +41,15 @@ pub trait WebPage: Serialize + Sized { // TODO: We could cache similar pages using the `&Context` fn into_response(self, req: &Request) -> IronResult { let ctx = Context::from_serialize(&self).unwrap(); - let rendered = req - .extensions - .get::() - .expect("missing TemplateData from the request extensions") - .templates - .load() - .render(&self.template(), &ctx) - .unwrap(); + let rendered = ctry!( + req, + req.extensions + .get::() + .expect("missing TemplateData from the request extensions") + .templates + .load() + .render(&self.template(), &ctx) + ); let mut response = Response::with((self.get_status(), rendered)); response.headers.set(Self::content_type());