diff --git a/src/html_error.rs b/src/html_error.rs new file mode 100644 index 0000000..a914355 --- /dev/null +++ b/src/html_error.rs @@ -0,0 +1,37 @@ +use askama::Template; + +use gotham::helpers::http::response::create_response; +use gotham::state::State; + +use hyper::{Body, Response, StatusCode}; +use mime; + +#[derive(Debug, Template)] +#[template(path = "error.html")] +pub struct HtmlError { + site_url: String, + error_number: u16, + error_description: String, +} + +pub fn create_error_response( + status: StatusCode, + site_url: String, + state: &State, +) -> Response { + let template = HtmlError { + site_url, + error_number: status.as_u16(), + error_description: status.canonical_reason().unwrap_or("").into(), + }; + + match template.render() { + Ok(content) => create_response(&state, status, mime::TEXT_HTML_UTF_8, content.into_bytes()), + Err(_) => create_response( + &state, + StatusCode::INTERNAL_SERVER_ERROR, + mime::TEXT_PLAIN, + Body::from("500 INTERNAL SERVER ERROR"), + ), + } +} diff --git a/src/main.rs b/src/main.rs index 2ede990..03a2c60 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod config; +mod html_error; mod logger; mod paste; mod result; diff --git a/src/routes/edit.rs b/src/routes/edit.rs index 7a20b5b..27e2abd 100644 --- a/src/routes/edit.rs +++ b/src/routes/edit.rs @@ -1,16 +1,18 @@ use askama::Template; use futures::future; -use gotham::handler::{HandlerFuture, IntoHandlerError}; -use gotham::helpers::http::response::{create_empty_response, create_response}; +use gotham::handler::HandlerFuture; +use gotham::helpers::http::response::create_response; use gotham::state::{FromState, State}; use gotham_derive::{StateData, StaticResponseExtender}; use hyper::StatusCode; +use log::error; use mime; use serde_derive::Deserialize; use crate::config::Config; +use crate::html_error::create_error_response; use crate::paste::Paste; use crate::syntax::SYNTAXES; @@ -38,33 +40,36 @@ pub fn route(mut state: State) -> Box { let mut path = config.data_directory.clone(); path.push(id.clone()); - match Paste::from_file(path) { + let res = match Paste::from_file(path) { Ok(paste) => { let template = Edit { id, dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(), text: paste.text, - site_url: config.url, + site_url: config.url.clone(), syntaxes: SYNTAXES.to_vec(), syntax: paste.lang, }; - let res = match template.render() { + match template.render() { Ok(content) => create_response( &state, StatusCode::OK, mime::TEXT_HTML_UTF_8, content.into_bytes(), ), - Err(_) => create_empty_response(&state, StatusCode::INTERNAL_SERVER_ERROR), - }; - - future::ok((state, res)) + Err(e) => { + error!("edit.rs(10): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) + } + } } Err(e) => { - let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); - future::err((state, io_error.into_handler_error())) + error!("edit.rs(20): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) } - } + }; + + future::ok((state, res)) }) } diff --git a/src/routes/index.rs b/src/routes/index.rs index a41800c..0648f15 100644 --- a/src/routes/index.rs +++ b/src/routes/index.rs @@ -2,13 +2,15 @@ use askama::Template; use futures::future; use gotham::handler::HandlerFuture; -use gotham::helpers::http::response::{create_empty_response, create_response}; +use gotham::helpers::http::response::create_response; use gotham::state::{FromState, State}; use hyper::StatusCode; +use log::error; use mime; use crate::config::Config; +use crate::html_error::create_error_response; use crate::syntax::SYNTAXES; #[derive(Debug, Template)] @@ -24,7 +26,7 @@ pub fn route(mut state: State) -> Box { let template = Index { syntaxes: SYNTAXES.to_vec(), - site_url: config.url, + site_url: config.url.clone(), }; let res = match template.render() { @@ -34,7 +36,10 @@ pub fn route(mut state: State) -> Box { mime::TEXT_HTML_UTF_8, content.into_bytes(), ), - Err(_) => create_empty_response(&state, StatusCode::INTERNAL_SERVER_ERROR), + Err(e) => { + error!("index.rs: {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) + } }; future::ok((state, res)) diff --git a/src/routes/raw.rs b/src/routes/raw.rs index 7ed3516..9ec95f4 100644 --- a/src/routes/raw.rs +++ b/src/routes/raw.rs @@ -1,15 +1,17 @@ use futures::future; -use gotham::handler::{HandlerFuture, IntoHandlerError}; +use gotham::handler::HandlerFuture; use gotham::helpers::http::response::create_response; use gotham::state::{FromState, State}; use gotham_derive::{StateData, StaticResponseExtender}; use hyper::StatusCode; +use log::error; use mime; use serde_derive::Deserialize; use crate::config::Config; +use crate::html_error::create_error_response; use crate::paste::Paste; #[derive(Deserialize, StateData, StaticResponseExtender)] @@ -25,16 +27,14 @@ pub fn get(mut state: State) -> Box { let mut path = config.data_directory; path.push(id); - match Paste::from_file(path) { - Ok(paste) => { - let res = create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, paste.text); - - future::ok((state, res)) - } + let res = match Paste::from_file(path) { + Ok(paste) => create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, paste.text), Err(e) => { - let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); - future::err((state, io_error.into_handler_error())) + error!("raw.rs: {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) } - } + }; + + future::ok((state, res)) }) } diff --git a/src/routes/submit.rs b/src/routes/submit.rs index 26a2170..48c7667 100644 --- a/src/routes/submit.rs +++ b/src/routes/submit.rs @@ -1,18 +1,19 @@ use std::collections::HashMap; -use std::io::{Error, ErrorKind}; use futures::{future, Future, Stream}; -use gotham::handler::{HandlerFuture, IntoHandlerError}; +use gotham::handler::HandlerFuture; use gotham::helpers::http::response::create_response; use gotham::state::{FromState, State}; use hyper::Response; use hyper::{Body, StatusCode}; +use log::error; use mime; use url::form_urlencoded; use crate::config::Config; +use crate::html_error::create_error_response; use crate::paste::Paste; pub fn put(mut state: State) -> Box { @@ -20,7 +21,7 @@ pub fn put(mut state: State) -> Box { Body::take_from(&mut state).concat2().then(|body| { let config = Config::take_from(&mut state); - match body { + let res = match body { Ok(b) => { let body_content = b.into_bytes(); let text = String::from_utf8(body_content.as_ref().to_vec()).unwrap(); @@ -30,28 +31,40 @@ pub fn put(mut state: State) -> Box { let mut path = config.data_directory.clone(); path.push(paste.id.clone()); - if let Err(e) = paste.to_file(path) { - let err = Error::new(ErrorKind::Other, e.description()); - future::err((state, err.into_handler_error())) - } else { - let res = create_response( + match paste.to_file(path) { + Ok(_) => create_response( &state, StatusCode::OK, mime::TEXT_PLAIN, format!("{}/{}\n", config.url, paste.id), - ); - - future::ok((state, res)) + ), + Err(e) => { + error!("submit.rs(10): {:?}", e); + create_error_response( + StatusCode::INTERNAL_SERVER_ERROR, + config.url, + &state, + ) + } } } Err(e) => { - let err = Error::new(ErrorKind::Other, e.description()); - future::err((state, err.into_handler_error())) + error!("submit.rs(20): {:?}", e); + create_error_response( + StatusCode::INTERNAL_SERVER_ERROR, + config.url, + &state, + ) } } } - Err(e) => future::err((state, e.into_handler_error())), - } + Err(e) => { + error!("submit.rs(30): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) + } + }; + + future::ok((state, res)) }) }) } @@ -60,7 +73,8 @@ pub fn post(mut state: State) -> Box { Box::new({ Body::take_from(&mut state).concat2().then(|body| { let config = Config::take_from(&mut state); - match body { + + let res = match body { Ok(b) => { let body_content = b.into_bytes(); let form_map: HashMap = form_urlencoded::parse(&body_content) @@ -68,30 +82,44 @@ pub fn post(mut state: State) -> Box { .map(|x| x) .collect(); - if let Ok(paste) = Paste::from_form(form_map, config.salt) { - let mut path = config.data_directory; - path.push(paste.id.clone()); + match Paste::from_form(form_map, config.salt) { + Ok(paste) => { + let mut path = config.data_directory; + path.push(paste.id.clone()); - if let Err(e) = paste.to_file(path) { - let err = Error::new(ErrorKind::Other, e.description()); - return future::err((state, err.into_handler_error())); + match paste.to_file(path) { + Ok(_) => Response::builder() + .status(303) + .header("Location", format!("/{}", paste.id)) + .body(Body::empty()) + .unwrap(), + Err(e) => { + error!("submit.rs(40): {:?}", e); + create_error_response( + StatusCode::INTERNAL_SERVER_ERROR, + config.url, + &state, + ) + } + } + } + Err(e) => { + error!("submit.rs(50): {:?}", e); + create_error_response( + StatusCode::INTERNAL_SERVER_ERROR, + config.url, + &state, + ) } - - let res = Response::builder() - .status(303) - .header("Location", format!("/{}", paste.id)) - .body(Body::empty()) - .unwrap(); - - future::ok((state, res)) - } else { - let res = create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, "ERR"); - - future::ok((state, res)) } } - Err(e) => future::err((state, e.into_handler_error())), - } + Err(e) => { + error!("submit.rs(60): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) + } + }; + + future::ok((state, res)) }) }) } diff --git a/src/routes/view.rs b/src/routes/view.rs index ff668a9..779c0aa 100644 --- a/src/routes/view.rs +++ b/src/routes/view.rs @@ -1,18 +1,20 @@ use askama::Template; use futures::future; -use gotham::handler::{HandlerFuture, IntoHandlerError}; -use gotham::helpers::http::response::{create_empty_response, create_response}; +use gotham::handler::HandlerFuture; +use gotham::helpers::http::response::create_response; use gotham::state::{FromState, State}; use gotham_derive::{StateData, StaticResponseExtender}; use hyper::StatusCode; +use log::error; use mime; use serde_derive::Deserialize; use syntect::html::ClassedHTMLGenerator; use crate::config::Config; +use crate::html_error::create_error_response; use crate::paste::Paste; use crate::syntax::SYNTAX_SET; @@ -40,7 +42,7 @@ pub fn get(mut state: State) -> Box { let mut path = config.data_directory.clone(); path.push(id.clone()); - match Paste::from_file(path) { + let res = match Paste::from_file(path) { Ok(paste) => { let text_lines: Vec = paste.text.lines().map(|s| s.into()).collect(); let index_len = format!("{}", text_lines.len()).len(); @@ -60,26 +62,29 @@ pub fn get(mut state: State) -> Box { dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(), text_lines: high_lines, index_len, - site_url: config.url, + site_url: config.url.clone(), syntax: paste.lang, }; - let res = match template.render() { + match template.render() { Ok(content) => create_response( &state, StatusCode::OK, mime::TEXT_HTML_UTF_8, content.into_bytes(), ), - Err(_) => create_empty_response(&state, StatusCode::INTERNAL_SERVER_ERROR), - }; - - future::ok((state, res)) + Err(e) => { + error!("view.rs(10): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) + } + } } Err(e) => { - let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); - future::err((state, io_error.into_handler_error())) + error!("view.rs(20): {:?}", e); + create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state) } - } + }; + + future::ok((state, res)) }) } diff --git a/static/pastebucket.css b/static/pastebucket.css index 4e566e7..69ed7a9 100644 --- a/static/pastebucket.css +++ b/static/pastebucket.css @@ -167,3 +167,19 @@ main > div > div > div.line { span.hljs { padding: 0 !important; } + + +div.error { + text-align: center; +} + +div.error > div.error_number { + font-size: xx-large; + font-weight: bold; + color: red; + border-bottom: 1px gray dashed; +} + +div.error > div.error_description { + padding-top: .5rem; +} diff --git a/templates/error.html b/templates/error.html new file mode 100644 index 0000000..7b50698 --- /dev/null +++ b/templates/error.html @@ -0,0 +1,20 @@ + + + + + pastebucket :: error + + + +
+

pastebucket

+
+
+
+
+
{{error_number}}
+
{{error_description}}
+
+
+ +