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