From a85f29d3a89cc19b3c00751c9be33e483c453edf Mon Sep 17 00:00:00 2001
From: Philippe Loctaux
Date: Tue, 28 Feb 2023 17:28:16 +0100
Subject: [PATCH] error: added error catchers, error responder to respond with
template, basic error templates
---
crates/ezidam/src/error/catchers.rs | 22 +++++++++++++
crates/ezidam/src/error/mod.rs | 32 +++++++++++++++++++
crates/ezidam/src/error/responder.rs | 15 +++++++++
crates/ezidam/src/error/status_code.rs | 26 +++++++++++++++
crates/ezidam/templates/base.html.tera | 14 ++++++++
crates/ezidam/templates/errors/404.html.tera | 6 ++++
crates/ezidam/templates/errors/500.html.tera | 6 ++++
.../ezidam/templates/errors/unknown.html.tera | 7 ++++
8 files changed, 128 insertions(+)
create mode 100644 crates/ezidam/src/error/catchers.rs
create mode 100644 crates/ezidam/src/error/mod.rs
create mode 100644 crates/ezidam/src/error/responder.rs
create mode 100644 crates/ezidam/src/error/status_code.rs
create mode 100644 crates/ezidam/templates/base.html.tera
create mode 100644 crates/ezidam/templates/errors/404.html.tera
create mode 100644 crates/ezidam/templates/errors/500.html.tera
create mode 100644 crates/ezidam/templates/errors/unknown.html.tera
diff --git a/crates/ezidam/src/error/catchers.rs b/crates/ezidam/src/error/catchers.rs
new file mode 100644
index 0000000..177afe1
--- /dev/null
+++ b/crates/ezidam/src/error/catchers.rs
@@ -0,0 +1,22 @@
+use super::{Error, StatusCode};
+use rocket::http::Status;
+use rocket::{catch, catchers, Build, Request, Rocket};
+
+#[catch(404)]
+fn not_found(req: &Request) -> Error {
+ Error::new(StatusCode::NotFound, req.uri())
+}
+
+#[catch(500)]
+fn internal_server_error(req: &Request) -> Error {
+ Error::new(StatusCode::InternalServerError, req.uri())
+}
+
+#[catch(default)]
+fn default(status: Status, req: &Request) -> Error {
+ Error::new(StatusCode::Unknown(status), req.uri())
+}
+
+pub fn register(rocket_builder: Rocket) -> Rocket {
+ rocket_builder.register("/", catchers![default, not_found, internal_server_error])
+}
diff --git a/crates/ezidam/src/error/mod.rs b/crates/ezidam/src/error/mod.rs
new file mode 100644
index 0000000..a4eb88a
--- /dev/null
+++ b/crates/ezidam/src/error/mod.rs
@@ -0,0 +1,32 @@
+pub(super) mod catchers;
+mod conversion;
+mod responder;
+mod status_code;
+
+use self::status_code::StatusCode;
+use rocket_dyn_templates::{context, Template};
+
+pub struct Error {
+ status: StatusCode,
+ template: Template,
+}
+
+impl Error {
+ fn new(status: StatusCode, message: M) -> Self {
+ Self {
+ status,
+ template: Template::render(
+ status.template_name(),
+ context! {
+ message: message.to_string(),
+ version: env!("CARGO_PKG_VERSION"),
+ http_code: status.http_code().code,
+ },
+ ),
+ }
+ }
+
+ pub fn internal_server_error(error: E) -> Self {
+ Self::new(StatusCode::InternalServerError, error)
+ }
+}
diff --git a/crates/ezidam/src/error/responder.rs b/crates/ezidam/src/error/responder.rs
new file mode 100644
index 0000000..e964e46
--- /dev/null
+++ b/crates/ezidam/src/error/responder.rs
@@ -0,0 +1,15 @@
+use rocket::{response, Request, Response};
+use rocket::response::Responder;
+use super::Error;
+
+impl<'r, 'o: 'r> Responder<'r, 'o> for Error {
+ fn respond_to(self, req: &Request) -> response::Result<'o> {
+ // Response for template
+ let template_response = self.template.respond_to(req)?;
+
+ // Set status for final response
+ Response::build_from(template_response)
+ .status(self.status.http_code())
+ .ok()
+ }
+}
diff --git a/crates/ezidam/src/error/status_code.rs b/crates/ezidam/src/error/status_code.rs
new file mode 100644
index 0000000..1eac50d
--- /dev/null
+++ b/crates/ezidam/src/error/status_code.rs
@@ -0,0 +1,26 @@
+use rocket::http::Status;
+
+#[derive(Copy, Clone)]
+pub(super) enum StatusCode {
+ NotFound,
+ InternalServerError,
+ Unknown(Status),
+}
+
+impl StatusCode {
+ pub fn http_code(self) -> Status {
+ match self {
+ StatusCode::NotFound => Status::NotFound,
+ StatusCode::InternalServerError => Status::InternalServerError,
+ StatusCode::Unknown(status) => status,
+ }
+ }
+
+ pub fn template_name(self) -> &'static str {
+ match self {
+ StatusCode::NotFound => "errors/404",
+ StatusCode::InternalServerError => "errors/500",
+ StatusCode::Unknown(_) => "errors/unknown",
+ }
+ }
+}
diff --git a/crates/ezidam/templates/base.html.tera b/crates/ezidam/templates/base.html.tera
new file mode 100644
index 0000000..f869950
--- /dev/null
+++ b/crates/ezidam/templates/base.html.tera
@@ -0,0 +1,14 @@
+
+
+
+
+{% block content %}{% endblock content %}
+
+
+
ezidam version {{ version }}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/crates/ezidam/templates/errors/404.html.tera b/crates/ezidam/templates/errors/404.html.tera
new file mode 100644
index 0000000..e7e675d
--- /dev/null
+++ b/crates/ezidam/templates/errors/404.html.tera
@@ -0,0 +1,6 @@
+{% extends "base" %}
+
+{% block content %}
+404 not found error!
+{{ message }}
+{% endblock content %}
\ No newline at end of file
diff --git a/crates/ezidam/templates/errors/500.html.tera b/crates/ezidam/templates/errors/500.html.tera
new file mode 100644
index 0000000..6b16ee1
--- /dev/null
+++ b/crates/ezidam/templates/errors/500.html.tera
@@ -0,0 +1,6 @@
+{% extends "base" %}
+
+{% block content %}
+500 internal error!
+{{ message }}
+{% endblock content %}
\ No newline at end of file
diff --git a/crates/ezidam/templates/errors/unknown.html.tera b/crates/ezidam/templates/errors/unknown.html.tera
new file mode 100644
index 0000000..d4e3877
--- /dev/null
+++ b/crates/ezidam/templates/errors/unknown.html.tera
@@ -0,0 +1,7 @@
+{% extends "base" %}
+
+{% block content %}
+unknown error!
+http code {{ http_code }}
+{{ message }}
+{% endblock content %}
\ No newline at end of file