From: Johann150 <
johann@qwertqwefsday.eu>
---
v1 was: add 404 page
Cargo.lock | 1 +
Cargo.toml | 1 +
src/errorpage.rs | 31 +++++++++++++++++++++++++++++++
src/main.rs | 13 ++++++++++---
templates/error.html | 9 +++++++++
5 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 src/errorpage.rs
create mode 100644 templates/error.html
diff --git a/Cargo.lock b/Cargo.lock
index f4d2325..38149c0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1167,6 +1167,7 @@ dependencies = [
"askama",
"askama_tide",
"async-std",
+ "async-trait",
"chrono",
"git2",
"once_cell",
diff --git a/Cargo.toml b/Cargo.toml
index c16d847..624ebbc 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,6 +12,7 @@ anyhow = "1.0"
askama = {version = "0.10", features = ["with-tide"]}
askama_tide = "0.13"
async-std = { version = "1.8.0", features = ["attributes"] }
+async-trait = "0.1.48"
chrono = "0.4"
git2 = {version="0.13", default-features = false}
once_cell = "1.7.2"
diff --git a/src/errorpage.rs b/src/errorpage.rs
new file mode 100644
index 0000000..dbfcba7
--- /dev/null
+++ b/src/errorpage.rs
@@ -0,0 +1,31 @@
+use askama::Template;
+use tide::{Middleware, Next, Request, StatusCode};
+
+#[derive(Template)]
+#[template(path = "error.html")]
+struct ErrorTemplate {
+ resource: String,
+ status: StatusCode,
+ message: String,
+}
+
+pub struct ErrorToErrorpage;
+
+#[async_trait::async_trait]
+impl<State: Clone + Send + Sync + 'static> Middleware<State> for ErrorToErrorpage{
+ async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> tide::Result {
+ let resource = req.url().path().to_string();
+ let mut response = next.run(req).await;
+ if let Some(err) = response.take_error() {
+ let status = err.status();
+ response = ErrorTemplate{
+ resource,
+ status,
+ message: err.into_inner().to_string(),
+ }.into();
+ response.set_status(status);
+ }
+
+ Ok(response)
+ }
+}
diff --git a/src/main.rs b/src/main.rs
index d2f390a..c1073c1 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -13,6 +13,8 @@ use syntect::highlighting::{Color, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet};
use tide::Request;
+mod errorpage;
+
#[derive(Deserialize, Debug)]
pub struct Config {
#[serde(default = "defaults::port")]
@@ -130,14 +132,18 @@ struct RepoHomeTemplate {
readme_text: String,
}
-fn repo_from_request(repo_name: &str) -> Result<Repository> {
+fn repo_from_request(repo_name: &str) -> Result<Repository, tide::Error> {
let repo_name = percent_encoding::percent_decode_str(repo_name)
.decode_utf8_lossy()
.into_owned();
let repo_path = Path::new(&CONFIG.projectroot).join(repo_name);
// TODO CLEAN PATH! VERY IMPORTANT! DONT FORGET!
- let r = Repository::open(repo_path)?;
- Ok(r)
+ Repository::open(repo_path).or_else(|_| {
+ Err(tide::Error::from_str(
+ 404,
+ "This repository does not exist.",
+ ))
+ })
}
async fn repo_home(req: Request<()>) -> tide::Result {
@@ -469,6 +475,7 @@ mod filters {
async fn main() -> Result<(), std::io::Error> {
tide::log::start();
let mut app = tide::new();
+ app.with(errorpage::ErrorToErrorpage);
app.at("/").get(index);
app.at("/robots.txt")
.serve_file("templates/static/robots.txt")?; // TODO configurable
diff --git a/templates/error.html b/templates/error.html
new file mode 100644
index 0000000..7a2c946
--- /dev/null
+++ b/templates/error.html
@@ -0,0 +1,9 @@
+{% extends "base.html" %}
+
+{% block content %}
+ <div class="page-title"><h1>Hmm, that did not work.</h1></div>
+ <div>
+ Something went wrong in getting "{{resource}}":<br>
+ {{status}} — {{message}}
+ </div>
+{% endblock %}
--
2.20.1