mirror of
https://mzte.de/git/LordMZTE/brevo
synced 2024-10-31 20:59:01 +01:00
add rejection handlers
This commit is contained in:
parent
6e3d6114ff
commit
0d8f70c2ab
4 changed files with 114 additions and 18 deletions
33
assets/404.html.tera
Normal file
33
assets/404.html.tera
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
|
||||||
|
<html>
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<title>brevo</title>
|
||||||
|
<style type="text/css" media="screen">
|
||||||
|
body {
|
||||||
|
background-color: #282a36;
|
||||||
|
color: #f8f8f2;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
|
||||||
|
#content {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div id="content">
|
||||||
|
<div>
|
||||||
|
<h1>404 Not Found</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
|
@ -1,17 +1,17 @@
|
||||||
use crate::util::gen_id;
|
use crate::util::{gen_id, make_link, render_reject};
|
||||||
use crate::util::make_link;
|
|
||||||
use crate::util::render_reject;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sqlx::Row;
|
use sqlx::Row;
|
||||||
use std::sync::Arc;
|
use std::{convert::Infallible, sync::Arc};
|
||||||
use tera::Context;
|
use tera::Context;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use warp::http::uri::InvalidUri;
|
|
||||||
use warp::redirect;
|
|
||||||
use warp::{
|
use warp::{
|
||||||
http::Uri,
|
body::BodyDeserializeError,
|
||||||
|
http::{uri::InvalidUri, Uri},
|
||||||
|
redirect,
|
||||||
reject::{self, Reject},
|
reject::{self, Reject},
|
||||||
reply, Rejection, Reply,
|
reply,
|
||||||
|
Rejection,
|
||||||
|
Reply,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{sqlargs, util::sql_reject, Brevo};
|
use crate::{sqlargs, util::sql_reject, Brevo};
|
||||||
|
@ -19,7 +19,7 @@ use crate::{sqlargs, util::sql_reject, Brevo};
|
||||||
pub async fn index(brevo: Arc<Brevo>) -> Result<Box<dyn Reply>, Rejection> {
|
pub async fn index(brevo: Arc<Brevo>) -> Result<Box<dyn Reply>, Rejection> {
|
||||||
let rendered = brevo.tera.render("index.html", &Context::new());
|
let rendered = brevo.tera.render("index.html", &Context::new());
|
||||||
match rendered {
|
match rendered {
|
||||||
Err(_) => Err(reject::custom(BrevoReject::RenderFail)),
|
Err(e) => Err(reject::custom(BrevoReject::RenderFail(e))),
|
||||||
Ok(r) => Ok(Box::new(reply::html(r))),
|
Ok(r) => Ok(Box::new(reply::html(r))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,6 +103,68 @@ pub async fn submit(form_data: SubmitForm, brevo: Arc<Brevo>) -> Result<Box<dyn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn handle_reject(
|
||||||
|
brevo: Arc<Brevo>,
|
||||||
|
err: Rejection,
|
||||||
|
) -> Result<Box<dyn Reply>, Infallible> {
|
||||||
|
match try_handle_reject(brevo, err).await {
|
||||||
|
Ok(x) => Ok(x),
|
||||||
|
Err(e) => {
|
||||||
|
log::error!("Unrecoverable reply error occured! {:?}", e);
|
||||||
|
Ok(Box::new(reply::html("ERROR!! see logs")))
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn try_handle_reject(
|
||||||
|
brevo: Arc<Brevo>,
|
||||||
|
err: Rejection,
|
||||||
|
) -> Result<Box<dyn Reply>, Rejection> {
|
||||||
|
if err.is_not_found() {
|
||||||
|
let rendered = brevo
|
||||||
|
.tera
|
||||||
|
.render("404.html", &Context::new())
|
||||||
|
.map_err(render_reject)?;
|
||||||
|
|
||||||
|
return Ok(Box::new(reply::html(rendered)));
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(rej) = err.find::<BrevoReject>() {
|
||||||
|
return match rej {
|
||||||
|
BrevoReject::SqlError(err) => {
|
||||||
|
log::error!("SQL error: {:?}", err);
|
||||||
|
Ok(Box::new(reply::html("SQL error! see logs.")))
|
||||||
|
},
|
||||||
|
|
||||||
|
BrevoReject::RenderFail(err) => {
|
||||||
|
log::error!("Template error: {:?}", err);
|
||||||
|
Ok(Box::new(reply::html(
|
||||||
|
"Failed to render template! see logs.",
|
||||||
|
)))
|
||||||
|
},
|
||||||
|
|
||||||
|
BrevoReject::UrlParseError(err) => {
|
||||||
|
log::error!("URL parse error: {:?}", err);
|
||||||
|
Ok(Box::new(reply::html("Not a valid URL!")))
|
||||||
|
},
|
||||||
|
|
||||||
|
BrevoReject::UriParseError(err) => {
|
||||||
|
log::error!("URI parse error: {:?}", err);
|
||||||
|
Ok(Box::new(reply::html("Not a valid URI!")))
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if err.find::<BodyDeserializeError>().is_some() {
|
||||||
|
return Ok(Box::new(reply::html(
|
||||||
|
"Invalid data! Did you enter a valid URI?",
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
|
||||||
|
log::error!("unknown rejection: {:?}", err);
|
||||||
|
Ok(Box::new(reply::html("Found unknown rejection! see logs")))
|
||||||
|
}
|
||||||
|
|
||||||
async fn make_table(brevo: Arc<Brevo>) -> Result<(), Rejection> {
|
async fn make_table(brevo: Arc<Brevo>) -> Result<(), Rejection> {
|
||||||
// can't parameterize VARCHAR len, but this should be safe
|
// can't parameterize VARCHAR len, but this should be safe
|
||||||
sqlx::query(&format!(
|
sqlx::query(&format!(
|
||||||
|
@ -133,7 +195,7 @@ pub struct SubmitForm {
|
||||||
// TODO: implement reject handerls
|
// TODO: implement reject handerls
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum BrevoReject {
|
pub enum BrevoReject {
|
||||||
RenderFail,
|
RenderFail(tera::Error),
|
||||||
SqlError(sqlx::Error),
|
SqlError(sqlx::Error),
|
||||||
UrlParseError(url::ParseError),
|
UrlParseError(url::ParseError),
|
||||||
UriParseError(InvalidUri),
|
UriParseError(InvalidUri),
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use anyhow::Context;
|
use anyhow::Context;
|
||||||
use rand::{rngs::StdRng, SeedableRng};
|
use rand::{rngs::StdRng, SeedableRng};
|
||||||
|
@ -6,6 +5,7 @@ use sqlx::MySqlPool;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use tera::Tera;
|
use tera::Tera;
|
||||||
|
use tokio::sync::Mutex;
|
||||||
use warp::Filter;
|
use warp::Filter;
|
||||||
|
|
||||||
mod config;
|
mod config;
|
||||||
|
@ -35,6 +35,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
tera.add_raw_templates(vec![
|
tera.add_raw_templates(vec![
|
||||||
("index.html", include_str!("../assets/index.html.tera")),
|
("index.html", include_str!("../assets/index.html.tera")),
|
||||||
("success.html", include_str!("../assets/success.html.tera")),
|
("success.html", include_str!("../assets/success.html.tera")),
|
||||||
|
("404.html", include_str!("../assets/404.html.tera")),
|
||||||
])
|
])
|
||||||
.context("error adding templates to tera")?;
|
.context("error adding templates to tera")?;
|
||||||
|
|
||||||
|
@ -47,6 +48,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
let brevo_idx = Arc::clone(&brevo);
|
let brevo_idx = Arc::clone(&brevo);
|
||||||
let brevo_submit = Arc::clone(&brevo);
|
let brevo_submit = Arc::clone(&brevo);
|
||||||
let brevo_srv = Arc::clone(&brevo);
|
let brevo_srv = Arc::clone(&brevo);
|
||||||
|
let brevo_reject = Arc::clone(&brevo);
|
||||||
|
|
||||||
let routes = warp::get()
|
let routes = warp::get()
|
||||||
.and(
|
.and(
|
||||||
|
@ -59,7 +61,8 @@ async fn main() -> anyhow::Result<()> {
|
||||||
.or(warp::post()
|
.or(warp::post()
|
||||||
.and(warp::body::content_length_limit(1024 * 16))
|
.and(warp::body::content_length_limit(1024 * 16))
|
||||||
.and(warp::body::form())
|
.and(warp::body::form())
|
||||||
.and_then(move |form_data| handlers::submit(form_data, Arc::clone(&brevo_submit))));
|
.and_then(move |form_data| handlers::submit(form_data, Arc::clone(&brevo_submit))))
|
||||||
|
.recover(move |err| handlers::handle_reject(Arc::clone(&brevo_reject), err));
|
||||||
|
|
||||||
warp::serve(routes).run(brevo_srv.config.bind_addr).await;
|
warp::serve(routes).run(brevo_srv.config.bind_addr).await;
|
||||||
|
|
||||||
|
|
10
src/util.rs
10
src/util.rs
|
@ -1,10 +1,8 @@
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::handlers::BrevoReject;
|
use crate::{handlers::BrevoReject, Brevo};
|
||||||
use crate::Brevo;
|
|
||||||
use rand::seq::IteratorRandom;
|
use rand::seq::IteratorRandom;
|
||||||
use warp::reject;
|
use warp::{reject, Rejection};
|
||||||
use warp::Rejection;
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! sqlargs {
|
macro_rules! sqlargs {
|
||||||
|
@ -22,8 +20,8 @@ pub fn sql_reject(e: sqlx::Error) -> Rejection {
|
||||||
reject::custom(BrevoReject::SqlError(e))
|
reject::custom(BrevoReject::SqlError(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_reject<T>(_: T) -> Rejection {
|
pub fn render_reject(err: tera::Error) -> Rejection {
|
||||||
reject::custom(BrevoReject::RenderFail)
|
reject::custom(BrevoReject::RenderFail(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn make_link(brevo: Arc<Brevo>, id: &str) -> Result<String, Rejection> {
|
pub fn make_link(brevo: Arc<Brevo>, id: &str) -> Result<String, Rejection> {
|
||||||
|
|
Loading…
Reference in a new issue