diff options
Diffstat (limited to 'src/web/responses.rs')
-rw-r--r-- | src/web/responses.rs | 135 |
1 files changed, 125 insertions, 10 deletions
diff --git a/src/web/responses.rs b/src/web/responses.rs index bcdcc0a..00af35a 100644 --- a/src/web/responses.rs +++ b/src/web/responses.rs @@ -12,10 +12,13 @@ use std::convert::Infallible; use bytes::Bytes; +use git_bug::replica::entity::id::prefix::IdPrefix; use http::{Response, StatusCode, Version}; use http_body_util::{BodyExt, Full, combinators::BoxBody}; +use vy::{IntoHtml, h1, p, pre}; -use crate::{error, git_bug::format::HtmlString}; +use super::generate::templates::make_page; +use crate::error; pub(super) fn html_response<T: Into<Bytes>>(html_text: T) -> Response<BoxBody<Bytes, Infallible>> { html_response_status(html_text, StatusCode::OK) @@ -28,6 +31,15 @@ pub(super) fn html_response_status<T: Into<Bytes>>( html_response_status_content_type(html_text, status, "text/html") } +pub(super) fn redirect(target: &str) -> Response<BoxBody<Bytes, Infallible>> { + Response::builder() + .status(StatusCode::MOVED_PERMANENTLY) + .version(Version::HTTP_2) + .header("Location", target) + .body(full("")) + .expect("This is hardcoded and will build") +} + pub(super) fn html_response_status_content_type<T: Into<Bytes>>( html_text: T, status: StatusCode, @@ -36,26 +48,129 @@ pub(super) fn html_response_status_content_type<T: Into<Bytes>>( Response::builder() .status(status) .version(Version::HTTP_2) - .header("Content-Type", format!("{}; charset=utf-8", content_type)) + .header("Content-Type", format!("{content_type}; charset=utf-8")) .header("x-content-type-options", "nosniff") .header("x-frame-options", "SAMEORIGIN") .body(full(html_text)) .expect("This will always build") } -fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, Infallible> { +pub(super) fn full<T: Into<Bytes>>(chunk: T) -> BoxBody<Bytes, Infallible> { Full::new(chunk.into()).boxed() } -// FIXME: Not all errors should return `INTERNAL_SERVER_ERROR`. <2025-03-08> impl error::Error { + #[allow(clippy::too_many_lines)] pub fn into_response(self) -> Response<BoxBody<Bytes, Infallible>> { - html_response_status( - format!( - "<h1> Internal server error. </h1> <pre>Error: {}</pre>", - HtmlString::from(self.to_string()) + match self { + error::Error::ConfigParse { .. } + | error::Error::ProjectListRead { .. } + | error::Error::ConfigRead { .. } + | error::Error::RepoGetReferences(_) + | error::Error::RepoIssueRead(_) + | error::Error::RepoIdentityRead(_) + | error::Error::RepoFind { .. } + | error::Error::RepoRefsIter(_) + | error::Error::RepoRefsPrefixed { .. } + | error::Error::TcpBind { .. } + | error::Error::RepoOpen { .. } + | error::Error::TcpAccept { .. } => html_response_status( + make_page( + ( + h1!("Internal server error"), + pre!(format!("Error {}", self.to_string())), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::INTERNAL_SERVER_ERROR, + ), + error::Error::NotGitBug { path } => html_response_status( + make_page( + ( + h1!("Expectation Failed"), + p!( + "Repository '", + path.display().to_string(), + "' has no git bug data to show." + ), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::EXPECTATION_FAILED, + ), + error::Error::IssuesPrefixMissing { prefix, err } => html_response_status( + make_page( + ( + h1!("Expectation Failed"), + p!( + "There is no issue associated with the prefix ", + "'", + prefix.to_string(), + "': ", + err.to_string() + ), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::EXPECTATION_FAILED, + ), + error::Error::IssuesPrefixParse { prefix, error } => html_response_status( + make_page( + ( + h1!("Expectation Failed"), + p!( + "The prefix '", + prefix, + "' cannot be interperted as a prefix", + ), + p!(error.to_string()), + p!( + "The prefix is composed of ", + IdPrefix::REQUIRED_LENGTH, + " or more hex chars." + ), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::EXPECTATION_FAILED, + ), + error::Error::NotFound(path_buf) => html_response_status( + make_page( + ( + h1!("Expectation Failed"), + p!( + "The path '", + path_buf.display().to_string(), + "' was unkonwn", + ), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::EXPECTATION_FAILED, + ), + error::Error::InvalidQuery { err, query } => html_response_status( + make_page( + ( + h1!("Expectation Failed"), + p!("The query '", query, "' was invalid",), + p!(err.to_string()), + ), + "Error page", + Some("Error | Back"), + ) + .into_string(), + StatusCode::EXPECTATION_FAILED, ), - StatusCode::INTERNAL_SERVER_ERROR, - ) + } } } |