html page for errors

master
rasul 5 years ago
parent 5401bcc268
commit 51f458fb1a

@ -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<Body> {
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"),
),
}
}

@ -1,4 +1,5 @@
mod config; mod config;
mod html_error;
mod logger; mod logger;
mod paste; mod paste;
mod result; mod result;

@ -1,16 +1,18 @@
use askama::Template; use askama::Template;
use futures::future; use futures::future;
use gotham::handler::{HandlerFuture, IntoHandlerError}; 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 gotham::state::{FromState, State};
use gotham_derive::{StateData, StaticResponseExtender}; use gotham_derive::{StateData, StaticResponseExtender};
use hyper::StatusCode; use hyper::StatusCode;
use log::error;
use mime; use mime;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use crate::config::Config; use crate::config::Config;
use crate::html_error::create_error_response;
use crate::paste::Paste; use crate::paste::Paste;
use crate::syntax::SYNTAXES; use crate::syntax::SYNTAXES;
@ -38,33 +40,36 @@ pub fn route(mut state: State) -> Box<HandlerFuture> {
let mut path = config.data_directory.clone(); let mut path = config.data_directory.clone();
path.push(id.clone()); path.push(id.clone());
match Paste::from_file(path) { let res = match Paste::from_file(path) {
Ok(paste) => { Ok(paste) => {
let template = Edit { let template = Edit {
id, id,
dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(), dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(),
text: paste.text, text: paste.text,
site_url: config.url, site_url: config.url.clone(),
syntaxes: SYNTAXES.to_vec(), syntaxes: SYNTAXES.to_vec(),
syntax: paste.lang, syntax: paste.lang,
}; };
let res = match template.render() { match template.render() {
Ok(content) => create_response( Ok(content) => create_response(
&state, &state,
StatusCode::OK, StatusCode::OK,
mime::TEXT_HTML_UTF_8, mime::TEXT_HTML_UTF_8,
content.into_bytes(), content.into_bytes(),
), ),
Err(_) => create_empty_response(&state, StatusCode::INTERNAL_SERVER_ERROR),
};
future::ok((state, res))
}
Err(e) => { Err(e) => {
let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); error!("edit.rs(10): {:?}", e);
future::err((state, io_error.into_handler_error())) create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
} }
} }
Err(e) => {
error!("edit.rs(20): {:?}", e);
create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
};
future::ok((state, res))
}) })
} }

@ -2,13 +2,15 @@ use askama::Template;
use futures::future; use futures::future;
use gotham::handler::HandlerFuture; 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 gotham::state::{FromState, State};
use hyper::StatusCode; use hyper::StatusCode;
use log::error;
use mime; use mime;
use crate::config::Config; use crate::config::Config;
use crate::html_error::create_error_response;
use crate::syntax::SYNTAXES; use crate::syntax::SYNTAXES;
#[derive(Debug, Template)] #[derive(Debug, Template)]
@ -24,7 +26,7 @@ pub fn route(mut state: State) -> Box<HandlerFuture> {
let template = Index { let template = Index {
syntaxes: SYNTAXES.to_vec(), syntaxes: SYNTAXES.to_vec(),
site_url: config.url, site_url: config.url.clone(),
}; };
let res = match template.render() { let res = match template.render() {
@ -34,7 +36,10 @@ pub fn route(mut state: State) -> Box<HandlerFuture> {
mime::TEXT_HTML_UTF_8, mime::TEXT_HTML_UTF_8,
content.into_bytes(), 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)) future::ok((state, res))

@ -1,15 +1,17 @@
use futures::future; use futures::future;
use gotham::handler::{HandlerFuture, IntoHandlerError}; use gotham::handler::HandlerFuture;
use gotham::helpers::http::response::create_response; use gotham::helpers::http::response::create_response;
use gotham::state::{FromState, State}; use gotham::state::{FromState, State};
use gotham_derive::{StateData, StaticResponseExtender}; use gotham_derive::{StateData, StaticResponseExtender};
use hyper::StatusCode; use hyper::StatusCode;
use log::error;
use mime; use mime;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use crate::config::Config; use crate::config::Config;
use crate::html_error::create_error_response;
use crate::paste::Paste; use crate::paste::Paste;
#[derive(Deserialize, StateData, StaticResponseExtender)] #[derive(Deserialize, StateData, StaticResponseExtender)]
@ -25,16 +27,14 @@ pub fn get(mut state: State) -> Box<HandlerFuture> {
let mut path = config.data_directory; let mut path = config.data_directory;
path.push(id); path.push(id);
match Paste::from_file(path) { let res = match Paste::from_file(path) {
Ok(paste) => { Ok(paste) => create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, paste.text),
let res = create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, paste.text);
future::ok((state, res))
}
Err(e) => { Err(e) => {
let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); error!("raw.rs: {:?}", e);
future::err((state, io_error.into_handler_error())) create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
} }
};
future::ok((state, res))
}) })
} }

@ -1,18 +1,19 @@
use std::collections::HashMap; use std::collections::HashMap;
use std::io::{Error, ErrorKind};
use futures::{future, Future, Stream}; use futures::{future, Future, Stream};
use gotham::handler::{HandlerFuture, IntoHandlerError}; use gotham::handler::HandlerFuture;
use gotham::helpers::http::response::create_response; use gotham::helpers::http::response::create_response;
use gotham::state::{FromState, State}; use gotham::state::{FromState, State};
use hyper::Response; use hyper::Response;
use hyper::{Body, StatusCode}; use hyper::{Body, StatusCode};
use log::error;
use mime; use mime;
use url::form_urlencoded; use url::form_urlencoded;
use crate::config::Config; use crate::config::Config;
use crate::html_error::create_error_response;
use crate::paste::Paste; use crate::paste::Paste;
pub fn put(mut state: State) -> Box<HandlerFuture> { pub fn put(mut state: State) -> Box<HandlerFuture> {
@ -20,7 +21,7 @@ pub fn put(mut state: State) -> Box<HandlerFuture> {
Body::take_from(&mut state).concat2().then(|body| { Body::take_from(&mut state).concat2().then(|body| {
let config = Config::take_from(&mut state); let config = Config::take_from(&mut state);
match body { let res = match body {
Ok(b) => { Ok(b) => {
let body_content = b.into_bytes(); let body_content = b.into_bytes();
let text = String::from_utf8(body_content.as_ref().to_vec()).unwrap(); let text = String::from_utf8(body_content.as_ref().to_vec()).unwrap();
@ -30,28 +31,40 @@ pub fn put(mut state: State) -> Box<HandlerFuture> {
let mut path = config.data_directory.clone(); let mut path = config.data_directory.clone();
path.push(paste.id.clone()); path.push(paste.id.clone());
if let Err(e) = paste.to_file(path) { match paste.to_file(path) {
let err = Error::new(ErrorKind::Other, e.description()); Ok(_) => create_response(
future::err((state, err.into_handler_error()))
} else {
let res = create_response(
&state, &state,
StatusCode::OK, StatusCode::OK,
mime::TEXT_PLAIN, mime::TEXT_PLAIN,
format!("{}/{}\n", config.url, paste.id), format!("{}/{}\n", config.url, paste.id),
); ),
Err(e) => {
future::ok((state, res)) error!("submit.rs(10): {:?}", e);
create_error_response(
StatusCode::INTERNAL_SERVER_ERROR,
config.url,
&state,
)
}
} }
} }
Err(e) => { Err(e) => {
let err = Error::new(ErrorKind::Other, e.description()); error!("submit.rs(20): {:?}", e);
future::err((state, err.into_handler_error())) 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<HandlerFuture> {
Box::new({ Box::new({
Body::take_from(&mut state).concat2().then(|body| { Body::take_from(&mut state).concat2().then(|body| {
let config = Config::take_from(&mut state); let config = Config::take_from(&mut state);
match body {
let res = match body {
Ok(b) => { Ok(b) => {
let body_content = b.into_bytes(); let body_content = b.into_bytes();
let form_map: HashMap<String, String> = form_urlencoded::parse(&body_content) let form_map: HashMap<String, String> = form_urlencoded::parse(&body_content)
@ -68,30 +82,44 @@ pub fn post(mut state: State) -> Box<HandlerFuture> {
.map(|x| x) .map(|x| x)
.collect(); .collect();
if let Ok(paste) = Paste::from_form(form_map, config.salt) { match Paste::from_form(form_map, config.salt) {
Ok(paste) => {
let mut path = config.data_directory; let mut path = config.data_directory;
path.push(paste.id.clone()); path.push(paste.id.clone());
if let Err(e) = paste.to_file(path) { match paste.to_file(path) {
let err = Error::new(ErrorKind::Other, e.description()); Ok(_) => Response::builder()
return future::err((state, err.into_handler_error()));
}
let res = Response::builder()
.status(303) .status(303)
.header("Location", format!("/{}", paste.id)) .header("Location", format!("/{}", paste.id))
.body(Body::empty()) .body(Body::empty())
.unwrap(); .unwrap(),
Err(e) => {
future::ok((state, res)) error!("submit.rs(40): {:?}", e);
} else { create_error_response(
let res = create_response(&state, StatusCode::OK, mime::TEXT_PLAIN, "ERR"); StatusCode::INTERNAL_SERVER_ERROR,
config.url,
future::ok((state, res)) &state,
)
}
}
} }
Err(e) => {
error!("submit.rs(50): {:?}", 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(60): {:?}", e);
create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
};
future::ok((state, res))
}) })
}) })
} }

@ -1,18 +1,20 @@
use askama::Template; use askama::Template;
use futures::future; use futures::future;
use gotham::handler::{HandlerFuture, IntoHandlerError}; 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 gotham::state::{FromState, State};
use gotham_derive::{StateData, StaticResponseExtender}; use gotham_derive::{StateData, StaticResponseExtender};
use hyper::StatusCode; use hyper::StatusCode;
use log::error;
use mime; use mime;
use serde_derive::Deserialize; use serde_derive::Deserialize;
use syntect::html::ClassedHTMLGenerator; use syntect::html::ClassedHTMLGenerator;
use crate::config::Config; use crate::config::Config;
use crate::html_error::create_error_response;
use crate::paste::Paste; use crate::paste::Paste;
use crate::syntax::SYNTAX_SET; use crate::syntax::SYNTAX_SET;
@ -40,7 +42,7 @@ pub fn get(mut state: State) -> Box<HandlerFuture> {
let mut path = config.data_directory.clone(); let mut path = config.data_directory.clone();
path.push(id.clone()); path.push(id.clone());
match Paste::from_file(path) { let res = match Paste::from_file(path) {
Ok(paste) => { Ok(paste) => {
let text_lines: Vec<String> = paste.text.lines().map(|s| s.into()).collect(); let text_lines: Vec<String> = paste.text.lines().map(|s| s.into()).collect();
let index_len = format!("{}", text_lines.len()).len(); let index_len = format!("{}", text_lines.len()).len();
@ -60,26 +62,29 @@ pub fn get(mut state: State) -> Box<HandlerFuture> {
dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(), dt: paste.dt.format("%Y-%m-%dT%H:%MZ").to_string(),
text_lines: high_lines, text_lines: high_lines,
index_len, index_len,
site_url: config.url, site_url: config.url.clone(),
syntax: paste.lang, syntax: paste.lang,
}; };
let res = match template.render() { match template.render() {
Ok(content) => create_response( Ok(content) => create_response(
&state, &state,
StatusCode::OK, StatusCode::OK,
mime::TEXT_HTML_UTF_8, mime::TEXT_HTML_UTF_8,
content.into_bytes(), content.into_bytes(),
), ),
Err(_) => create_empty_response(&state, StatusCode::INTERNAL_SERVER_ERROR),
};
future::ok((state, res))
}
Err(e) => { Err(e) => {
let io_error = std::io::Error::new(std::io::ErrorKind::Other, e.description()); error!("view.rs(10): {:?}", e);
future::err((state, io_error.into_handler_error())) create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
} }
} }
Err(e) => {
error!("view.rs(20): {:?}", e);
create_error_response(StatusCode::INTERNAL_SERVER_ERROR, config.url, &state)
}
};
future::ok((state, res))
}) })
} }

@ -167,3 +167,19 @@ main > div > div > div.line {
span.hljs { span.hljs {
padding: 0 !important; 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;
}

@ -0,0 +1,20 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>pastebucket :: error</title>
<link rel="stylesheet" href="/s/pastebucket.css">
</head>
<body>
<header>
<h1><a href="{{site_url|safe}}">pastebucket</a></h1>
<hr>
</header>
<main>
<div class="error">
<div class="error_number">{{error_number}}</div>
<div class="error_description">{{error_description}}</div>
</div>
</main>
</body>
</html>
Loading…
Cancel
Save