From 598335b756fbc4b5ea62f9cf999a91b7751bdbbb Mon Sep 17 00:00:00 2001
From: Sxyntheon <jakob_kannenberg@icloud.com>
Date: Wed, 20 Nov 2024 18:54:03 +0100
Subject: [PATCH] fix http response codes

---
 backend/src/api/change_email.rs               |  25 +-
 backend/src/api/change_password.rs            |  35 ++-
 backend/src/api/change_untis_data.rs          |  19 +-
 backend/src/api/check_session.rs              |  12 +-
 backend/src/api/delete.rs                     |  18 +-
 backend/src/api/forgot_password.rs            |  21 +-
 backend/src/api/gdpr_data_compliance.rs       |  28 +-
 backend/src/api/get_free_rooms.rs             |  34 +--
 backend/src/api/get_lernbueros.rs             |  32 +--
 backend/src/api/get_timetable.rs              |  33 +--
 .../src/api/get_timetable_serviceworker.rs    |  33 +--
 backend/src/api/link/check_uuid.rs            |  14 +-
 backend/src/api/link/email_change.rs          |  42 +--
 backend/src/api/link/email_reset.rs           |  28 +-
 backend/src/api/link/password.rs              |  28 +-
 backend/src/api/link/verify.rs                |  20 +-
 backend/src/api/login.rs                      |  16 +-
 backend/src/api/logout.rs                     |   9 +-
 backend/src/api/logout_all.rs                 |  11 +-
 backend/src/api/mod.rs                        |   3 +-
 backend/src/api/register.rs                   |  24 +-
 backend/src/api/resend_mail.rs                |  27 +-
 backend/src/api/response.rs                   |  65 -----
 backend/src/api/verified.rs                   |  19 +-
 backend/src/api_wrapper/untis_client.rs       |   4 +-
 backend/src/api_wrapper/utils.rs              |   5 +
 backend/src/database/sessions.rs              |   2 +-
 backend/src/mail/mailing.rs                   |   2 +-
 backend/src/main.rs                           |   7 +-
 backend/src/models/links_model.rs             |   2 +-
 backend/src/models/manual_lb_model.rs         |   2 +-
 backend/src/models/model.rs                   |   2 +-
 backend/src/models/room_model.rs              |   2 +-
 backend/src/models/sessions_model.rs          |   2 +-
 backend/src/models/teacher_model.rs           |   2 +-
 backend/src/models/user_model.rs              |   2 +-
 backend/src/prelude.rs                        |  22 --
 frontend/compileServiceWorker.ts              |   7 +-
 frontend/public/manifest.webmanifest          |   3 +-
 frontend/src/api/dateHandling.ts              |   4 +-
 frontend/src/api/frontmatter.ts               |  18 +-
 frontend/src/api/main.ts                      |  39 ++-
 frontend/src/api/theBackend.ts                |  26 +-
 frontend/src/components/RegisterForm.tsx      |  15 +-
 .../components/plan-components/FreeRooms.tsx  |   2 +-
 .../components/plan-components/Lernbueros.tsx |  38 +--
 .../components/plan-components/Settings.tsx   |   8 +-
 .../plan-components/Stundenplan.tsx           |   4 +-
 .../settings-components/ChangeEmail.tsx       |   1 +
 .../settings-components/DeleteAccount.tsx     |   2 +-
 .../settings-components/ResetEmail.tsx        |   2 +-
 frontend/src/layouts/PlanLayout.astro         |  16 +-
 frontend/src/layouts/RootLayout.astro         | 258 +++++++++---------
 frontend/src/pwa/cachingStrategies.ts         |  12 +-
 frontend/src/pwa/serviceWorker.ts             |  39 ++-
 frontend/src/styles/Stundenplan.scss          |   1 -
 56 files changed, 525 insertions(+), 622 deletions(-)
 delete mode 100644 backend/src/api/response.rs
 delete mode 100644 backend/src/prelude.rs

diff --git a/backend/src/api/change_email.rs b/backend/src/api/change_email.rs
index e387863..38608f7 100644
--- a/backend/src/api/change_email.rs
+++ b/backend/src/api/change_email.rs
@@ -1,13 +1,13 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use chrono::{DateTime, Days, Utc};
 use lettre::message::header::ContentType;
 use log::error;
 use surrealdb::sql::Thing;
 
-use super::response::Response;
+
 use crate::{
-    mail::{
+    api_wrapper::utils::TextResponse, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
@@ -18,7 +18,7 @@ pub async fn change_email_get(
     id: Option<Identity>, db: ConnectionData, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".into())));
+        return Err(error::ErrorForbidden( "Not logged in"));
     }
 
     let id = id.unwrap();
@@ -26,7 +26,7 @@ pub async fn change_email_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error trying to get id.id()\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -35,12 +35,12 @@ pub async fn change_email_get(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+                return Err(error::ErrorInternalServerError( "Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error getting user from id\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -52,7 +52,7 @@ pub async fn change_email_get(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating link\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -60,7 +60,7 @@ pub async fn change_email_get(
         Ok(a) => a.replace("${{CHANGE_URL}}", &link),
         Err(e) => {
             error!("Error loading template\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -68,14 +68,15 @@ pub async fn change_email_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error building message\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     };
 
-    Ok(web::Json(Response::new_success("Sent E-Mail, check your inbox".to_string())))
+    Ok(web::Json(TextResponse { message: "Sent E-Mail, check your inbox".to_string()}))
 }
+
diff --git a/backend/src/api/change_password.rs b/backend/src/api/change_password.rs
index 6645d08..61c2b6c 100644
--- a/backend/src/api/change_password.rs
+++ b/backend/src/api/change_password.rs
@@ -1,6 +1,6 @@
 use actix_identity::Identity;
 use actix_web::{
-    web::{self, Json}, Responder, Result
+    error, web::{self, Json}, Responder, Result
 };
 use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
 use chrono::{Days, Utc};
@@ -10,13 +10,12 @@ use rand_core::OsRng;
 use serde::Deserialize;
 use surrealdb::sql::Thing;
 
-use super::response::Response;
 use crate::{
-    database::sessions::delete_user_sessions, mail::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, error::Error, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
-    }, prelude::Error, utils::password::valid_password
+    }, utils::password::valid_password
 };
 
 #[derive(Debug, Deserialize)]
@@ -30,7 +29,7 @@ pub async fn change_password_post(
     body: Json<PasswordChange>, id: Option<Identity>, db: ConnectionData, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".into())));
+        return Err(error::ErrorForbidden( "Not logged in"));
     }
 
     let id = id.unwrap();
@@ -38,7 +37,7 @@ pub async fn change_password_post(
         Ok(a) => a,
         Err(e) => {
             error!("Error trying to get id\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -47,12 +46,12 @@ pub async fn change_password_post(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+                return Err(error::ErrorInternalServerError( "Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error trying to get user\n{e}");
-            return Ok(Response::new_error(500, "Interal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Interal Server Error"));
         }
     };
 
@@ -61,12 +60,12 @@ pub async fn change_password_post(
     };
 
     if body.old_password == body.new_password {
-        return Ok(Response::new_error(400, "New Password can't be Old Password".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "New Password can't be Old Password"));
     }
 
     if user.verify_password(body.old_password.clone()).is_err() {
         debug!("Wrong password");
-        return Ok(Response::new_error(403, "Wrong password".into()).into());
+        return Err(error::ErrorForbidden( "Wrong password"));
     }
 
     let argon2 = Argon2::default();
@@ -76,7 +75,7 @@ pub async fn change_password_post(
         Ok(a) => a,
         Err(e) => {
             error!("Error hashing password\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -93,12 +92,12 @@ pub async fn change_password_post(
 
     if let Err(e) = User::update_replace(db.clone(), old_user.id, new_user.clone()).await {
         error!("Error updating user\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     }
 
     if let Err(e) = delete_user_sessions(db.clone(), new_user.clone().id.to_string()).await {
         error!("Error logging user out\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     }
 
     let expiry_time = Utc::now().checked_add_days(Days::new(2)).unwrap();
@@ -107,7 +106,7 @@ pub async fn change_password_post(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating link\n{e}");
-            return Ok(Response::new_error(500, "Error sending mail".into()).into());
+            return Err(error::ErrorInternalServerError( "Error sending mail"));
         }
     };
 
@@ -115,7 +114,7 @@ pub async fn change_password_post(
         Ok(a) => a.replace("${{RESET_URL}}", &reset_link),
         Err(e) => {
             error!("Error loading template\n{e}");
-            return Ok(Response::new_error(500, "Error sending mail".into()).into());
+            return Err(error::ErrorInternalServerError( "Error sending mail"));
         }
     };
 
@@ -124,14 +123,14 @@ pub async fn change_password_post(
             Ok(a) => a,
             Err(e) => {
                 error!("Error building mail\n{e}");
-                return Ok(Response::new_error(500, "Error sending mail".into()).into());
+                return Err(error::ErrorInternalServerError( "Error sending mail"));
             }
         };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        return Ok(Response::new_error(500, "Error sending mail".into()).into());
+        return Err(error::ErrorInternalServerError( "Error sending mail"));
     }
 
-    Ok(web::Json(Response::new_success("Successfully changed Password".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully changed Password".to_string()}))
 }
diff --git a/backend/src/api/change_untis_data.rs b/backend/src/api/change_untis_data.rs
index 5fa2ccb..0456019 100644
--- a/backend/src/api/change_untis_data.rs
+++ b/backend/src/api/change_untis_data.rs
@@ -1,12 +1,11 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::{error, warn};
 use serde::Deserialize;
 use surrealdb::sql::Thing;
 
-use super::response::Response;
 use crate::{
-    database::sessions::delete_user_sessions, internalError, models::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, models::{
         model::{ConnectionData, CRUD}, user_model::User
     }
 };
@@ -22,7 +21,7 @@ pub async fn change_untis_data_post(
     body: web::Json<UntisData>, db: ConnectionData, id: Option<Identity>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".into())));
+        return Err(error::ErrorForbidden( "Not logged in"));
     }
 
     let id = id.unwrap();
@@ -30,7 +29,7 @@ pub async fn change_untis_data_post(
         Ok(a) => Thing::from(a.split_once(':').unwrap()),
         Err(e) => {
             error!("Error trying to get id\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -39,17 +38,17 @@ pub async fn change_untis_data_post(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error trying to get user\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if user.verify_password(body.password.clone()).is_err() {
-        return Ok(web::Json(Response::new_error(403, "Incorrect Password".to_string())));
+        return Err(error::ErrorForbidden( "Incorrect Password".to_string()));
     }
 
     let new_user = User {
@@ -63,12 +62,12 @@ pub async fn change_untis_data_post(
 
     if let Err(e) = User::update_replace(db.clone(), id.clone(), new_user).await {
         error!("Error updating user\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     }
 
     if let Err(e) = delete_user_sessions(db, id.to_string()).await {
         warn!("Error deleting user sessions, ignoring\n{e}");
     }
 
-    Ok(web::Json(Response::new_success("Successfully changed Untis Data".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully changed Untis Data".to_string()}))
 }
diff --git a/backend/src/api/check_session.rs b/backend/src/api/check_session.rs
index 8f8e7fb..652a4be 100644
--- a/backend/src/api/check_session.rs
+++ b/backend/src/api/check_session.rs
@@ -1,19 +1,21 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::error;
 
-use crate::api::response::Response;
+use crate::api_wrapper::utils::TextResponse;
+
+
 
 pub async fn check_session_get(id: Option<Identity>) -> Result<impl Responder> {
     if let Some(id) = id {
         match id.id() {
-            Ok(_) => Ok(web::Json(Response::new_success("Authenticated".to_string()))),
+            Ok(_) => Ok(web::Json(TextResponse { message: "Authenticated".to_string()})),
             Err(e) => {
                 error!("Error trying to get id.id()\n{}", e);
-                Ok(Response::new_error(500, "NOPE Server Error".to_string()).into())
+                Err(error::ErrorInternalServerError( "NOPE Server Error".to_string()).into())
             }
         }
     } else {
-        Ok(Response::new_error(403, "Not Authenticated".to_string()).into())
+        Err(error::ErrorForbidden( "Not Authenticated".to_string()).into())
     }
 }
diff --git a/backend/src/api/delete.rs b/backend/src/api/delete.rs
index 6db005a..a31b277 100644
--- a/backend/src/api/delete.rs
+++ b/backend/src/api/delete.rs
@@ -1,11 +1,11 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::{error, warn};
 use serde::Deserialize;
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, database::sessions::delete_user_sessions, internalError, models::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, models::{
         model::{ConnectionData, CRUD}, user_model::User
     }
 };
@@ -19,7 +19,7 @@ pub async fn delete_post(
     body: web::Json<DeleteBody>, id: Option<Identity>, db: ConnectionData,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".into())));
+        return Err(error::ErrorForbidden( "Not logged in"));
     }
 
     let id = id.unwrap();
@@ -27,7 +27,7 @@ pub async fn delete_post(
         Ok(a) => Thing::from(a.split_once(':').unwrap()),
         Err(e) => {
             error!("Error trying to get id\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -36,18 +36,18 @@ pub async fn delete_post(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error trying to get user\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if user.verify_password(body.password.clone()).is_err() {
         warn!("Incorrect password");
-        return Ok(web::Json(Response::new_error(403, "Incorrect Password".into())));
+        return Err(error::ErrorForbidden( "Incorrect Password"));
     }
 
     if let Err(e) = delete_user_sessions(db.clone(), id.to_string()).await {
@@ -56,8 +56,8 @@ pub async fn delete_post(
 
     if let Err(e) = User::delete(db, id).await {
         error!("Failed to delete account\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     };
 
-    Ok(web::Json(Response::new_success("Deleted your Account, bye-bye!".to_string())))
+    Ok(web::Json(TextResponse { message: "Deleted your Account, bye-bye!".to_string()}))
 }
diff --git a/backend/src/api/forgot_password.rs b/backend/src/api/forgot_password.rs
index 58f7d04..a6497fa 100644
--- a/backend/src/api/forgot_password.rs
+++ b/backend/src/api/forgot_password.rs
@@ -1,12 +1,11 @@
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use chrono::{Days, Utc};
 use lettre::{message::header::ContentType, Address};
 use log::error;
 use serde::Deserialize;
 
-use super::response::Response;
 use crate::{
-    mail::{
+    api_wrapper::utils::TextResponse, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::ConnectionData, user_model::User
@@ -22,19 +21,19 @@ pub async fn forgot_password_post(
     body: web::Json<ForgotPassword>, db: ConnectionData, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if body.mail.parse::<Address>().is_err() {
-        return Ok(web::Json(Response::new_error(400, "Not a valid e-mail".into())));
+        return Err(error::ErrorUnprocessableEntity( "Not a valid e-mail"));
     }
 
     let user = match User::get_from_email(db.clone(), body.mail.clone()).await {
         Ok(a) => match a {
             Some(a) => a,
             None => {
-                return Ok(Response::new_error(404, "No account associated with e-mail".into()).into());
+                return Err(error::ErrorNotFound( "No account associated with e-mail"));
             }
         },
         Err(e) => {
             error!("Error getting user from mail\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -44,7 +43,7 @@ pub async fn forgot_password_post(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating link\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -52,7 +51,7 @@ pub async fn forgot_password_post(
         Ok(a) => a.replace("${{RESET_URL}}", &link),
         Err(e) => {
             error!("Error loading template\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -60,14 +59,14 @@ pub async fn forgot_password_post(
         Ok(a) => a,
         Err(e) => {
             error!("Error building mail\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     }
 
-    Ok(web::Json(Response::new_success("Sent E-Mail, check your Inbox".to_string())))
+    Ok(web::Json(TextResponse { message: "Sent E-Mail, check your Inbox".to_string()}))
 }
diff --git a/backend/src/api/gdpr_data_compliance.rs b/backend/src/api/gdpr_data_compliance.rs
index f2bbffa..29e3395 100644
--- a/backend/src/api/gdpr_data_compliance.rs
+++ b/backend/src/api/gdpr_data_compliance.rs
@@ -1,5 +1,5 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use chrono::Local;
 use lettre::{
     message::{header::ContentType, Attachment, Mailbox, MultiPart, SinglePart}, Message
@@ -9,7 +9,7 @@ use serde::Serialize;
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, internalError, mail::{
+    api_wrapper::utils::TextResponse, mail::{
         mailing::send_mail, utils::{load_template, Mailer}
     }, models::{
         links_model::Link, model::{ConnectionData, CRUD}, sessions_model::Session, user_model::User
@@ -27,7 +27,7 @@ pub async fn gdpr_data_compliance_get(
     id: Option<Identity>, db: ConnectionData, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".into())));
+        return Err(error::ErrorForbidden( "Not logged in"));
     }
 
     let id = id.unwrap();
@@ -35,7 +35,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => Thing::from(a.split_once(':').unwrap()),
         Err(e) => {
             error!("Error trying to get id\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -44,12 +44,12 @@ pub async fn gdpr_data_compliance_get(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error trying to get user\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -57,7 +57,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error trying to get links\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -65,7 +65,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error trying to get sessions\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -83,7 +83,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a.replace("${{TIMESTAMP}}", &timestamp),
         Err(e) => {
             error!("Error loading template\n{e}");
-            return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+            return Err(error::ErrorInternalServerError( "Internal Server Error"));
         }
     };
 
@@ -91,7 +91,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error parsing mail\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -99,7 +99,7 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error Serializing data to json\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -120,14 +120,14 @@ pub async fn gdpr_data_compliance_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error constructing message\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     };
 
-    Ok(web::Json(Response::new_success("Sent E-Mail, check your inbox".to_string())))
+    Ok(web::Json(TextResponse { message: "Sent E-Mail, check your inbox".to_string()}))
 }
diff --git a/backend/src/api/get_free_rooms.rs b/backend/src/api/get_free_rooms.rs
index 966098c..61cca64 100644
--- a/backend/src/api/get_free_rooms.rs
+++ b/backend/src/api/get_free_rooms.rs
@@ -1,15 +1,15 @@
 use actix_identity::Identity;
-use actix_web::{web, HttpRequest, Responder, Result};
+use actix_web::{error, web, HttpRequest, Responder, Result};
 use log::{debug, error};
 use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, api_wrapper::{
+    api_wrapper::{
         untis_client::UntisClient, utils::{FormattedFreeRoom, TimetableParameter}
-    }, models::{
+    }, error::Error, models::{
         model::{DBConnection, CRUD}, user_model::User
-    }, prelude::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
+    }, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
 };
 
 #[derive(Serialize)]
@@ -28,13 +28,13 @@ pub async fn get_free_rooms(
     db: web::Data<DBConnection>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".to_string())));
+        return Err(error::ErrorForbidden( "Not logged in".to_string()));
     }
 
     let jsessionid = if let Some(session_cookie) = req.cookie("JSESSIONID") {
         session_cookie.value().to_string()
     } else {
-        return Ok(Response::new_error(403, "No JSESSIONID provided".to_string()).into());
+        return Err(error::ErrorForbidden( "No JSESSIONID provided".to_string()).into());
     };
 
     let pot_user: Option<User> = User::get_from_id(
@@ -46,12 +46,12 @@ pub async fn get_free_rooms(
                     Thing::from(split.unwrap())
                 } else {
                     error!("ID in session_cookie is wrong???");
-                    return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                    return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
                 }
             }
             Err(e) => {
                 error!("Error getting Identity id\n{e}");
-                return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
             }
         },
     )
@@ -61,16 +61,12 @@ pub async fn get_free_rooms(
         Some(u) => u,
         None => {
             debug!("Deleted(?) User tried to log in with old session token");
-            return Ok(Response::new_error(404, "This account doesn't exist!".to_string()).into());
+            return Err(error::ErrorNotFound( "This account doesn't exist!".to_string()).into());
         }
     };
 
     if !user.verified {
-        return Ok(Response::new_error(
-            403,
-            "Account not verified! Check your E-Mails for a verification link".to_string(),
-        )
-        .into());
+        return Err(error::ErrorUnauthorized("Account not verified! Check your E-Mails for a verification link"));
     }
 
     let untis = match UntisClient::unsafe_init(
@@ -87,9 +83,9 @@ pub async fn get_free_rooms(
         Ok(u) => u,
         Err(e) => {
             if let Error::Reqwest(_) = e {
-                return Ok(Response::new_error(400, "You done fucked up".into()).into());
+                return Err(error::ErrorUnprocessableEntity( "You done fucked up"));
             } else {
-                return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &e.to_string()).into());
+                return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &e.to_string()).into());
             }
         }
     };
@@ -105,9 +101,9 @@ pub async fn get_free_rooms(
 
     let rooms = match untis.clone().get_free_rooms(TimetableParameter::default(untis, from, until)).await {
         Ok(rooms) => rooms,
-        Err(err) => {
-            return Ok(Response::from(Error::UntisError(err.to_string())).into());
+        Err(_err) => {
+            return Err(error::ErrorInternalServerError("Error while fetching rooms"));
         }
     };
-    Ok(Response::new_success(TimetableResponse { rooms }).into())
+    Ok(web::Json(TimetableResponse { rooms }))
 }
diff --git a/backend/src/api/get_lernbueros.rs b/backend/src/api/get_lernbueros.rs
index ebd61fb..6e3c15d 100644
--- a/backend/src/api/get_lernbueros.rs
+++ b/backend/src/api/get_lernbueros.rs
@@ -1,15 +1,15 @@
 use actix_identity::Identity;
-use actix_web::{web, HttpRequest, Responder, Result};
+use actix_web::{error, web, HttpRequest, Responder, Result};
 use log::{debug, error};
 use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, api_wrapper::{
+    api_wrapper::{
         untis_client::UntisClient, utils::{FormattedLesson, TimetableParameter}
     }, models::{
         model::{DBConnection, CRUD}, user_model::User
-    }, prelude::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
+    }, error::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
 };
 
 #[derive(Serialize)]
@@ -28,13 +28,13 @@ pub async fn get_lernbueros(
     db: web::Data<DBConnection>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".to_string())));
+        return Err(error::ErrorForbidden( "Not logged in".to_string()));
     }
 
     let jsessionid = if let Some(session_cookie) = req.cookie("JSESSIONID") {
         session_cookie.value().to_string()
     } else {
-        return Ok(Response::new_error(403, "No JSESSIONID provided".to_string()).into());
+        return Err(error::ErrorForbidden( "No JSESSIONID provided".to_string()).into());
     };
 
     let pot_user: Option<User> = User::get_from_id(
@@ -46,12 +46,12 @@ pub async fn get_lernbueros(
                     Thing::from(split.unwrap())
                 } else {
                     error!("ID in session_cookie is wrong???");
-                    return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                    return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
                 }
             }
             Err(e) => {
                 error!("Error getting Identity id\n{e}");
-                return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
             }
         },
     )
@@ -61,16 +61,12 @@ pub async fn get_lernbueros(
         Some(u) => u,
         None => {
             debug!("Deleted(?) User tried to log in with old session token");
-            return Ok(Response::new_error(404, "This account doesn't exist!".to_string()).into());
+            return Err(error::ErrorNotFound( "This account doesn't exist!".to_string()).into());
         }
     };
 
     if !user.verified {
-        return Ok(Response::new_error(
-            403,
-            "Account not verified! Check your E-Mails for a verification link".to_string(),
-        )
-        .into());
+        return Err(error::ErrorForbidden( "Account not verified! Check your E-Mails for a verification link"));
     }
 
     let untis = match UntisClient::unsafe_init(
@@ -87,9 +83,9 @@ pub async fn get_lernbueros(
         Ok(u) => u,
         Err(e) => {
             if let Error::Reqwest(_) = e {
-                return Ok(Response::new_error(400, "You done fucked up".into()).into());
+                return Err(error::ErrorUnprocessableEntity( "You done fucked up"));
             } else {
-                return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &e.to_string()).into());
+               return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &e.to_string()).into());
             }
         }
     };
@@ -105,9 +101,9 @@ pub async fn get_lernbueros(
     
     let lernbueros = match untis.clone().get_lernbueros(TimetableParameter::default(untis, from, until)).await {
         Ok(lernbueros) => lernbueros,
-        Err(err) => {
-            return Ok(Response::from(Error::UntisError(err.to_string())).into());
+        Err(_err) => {
+            return Err(error::ErrorInternalServerError("Error while fetching lbs"));
         }
     };
-    Ok(Response::new_success(TimetableResponse { lessons: lernbueros }).into())
+    Ok(web::Json(TimetableResponse { lessons: lernbueros }))
 }
diff --git a/backend/src/api/get_timetable.rs b/backend/src/api/get_timetable.rs
index fc30a41..249cc2f 100644
--- a/backend/src/api/get_timetable.rs
+++ b/backend/src/api/get_timetable.rs
@@ -1,17 +1,18 @@
 use actix_identity::Identity;
-use actix_web::{web, HttpRequest, Responder, Result};
+use actix_web::{error, web::{self}, HttpRequest, Responder, Result};
 use log::{debug, error};
 use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, api_wrapper::{
+    api_wrapper::{
         untis_client::UntisClient, utils::{FormattedLesson, TimetableParameter}
     }, models::{
         model::{DBConnection, CRUD}, user_model::User
-    }, prelude::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
+    }, error::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
 };
 
+
 #[derive(Serialize)]
 struct TimetableResponse {
     lessons: Vec<FormattedLesson>,
@@ -29,13 +30,13 @@ pub async fn get_timetable(
     db: web::Data<DBConnection>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".to_string())));
+        return Err(error::ErrorForbidden("Not logged in"));
     }
 
     let jsessionid = if let Some(session_cookie) = req.cookie("JSESSIONID") {
         session_cookie.value().to_string()
     } else {
-        return Ok(Response::new_error(403, "No JSESSIONID provided".to_string()).into());
+        return Err(error::ErrorForbidden( "No JSESSIONID provided".to_string()));
     };
 
     let pot_user: Option<User> = User::get_from_id(
@@ -47,12 +48,12 @@ pub async fn get_timetable(
                     Thing::from(split.unwrap())
                 } else {
                     error!("ID in session_cookie is wrong???");
-                    return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                    return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()));
                 }
             }
             Err(e) => {
                 error!("Error getting Identity id\n{e}");
-                return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()));
             }
         },
     )
@@ -62,16 +63,12 @@ pub async fn get_timetable(
         Some(u) => u,
         None => {
             debug!("Deleted(?) User tried to log in with old session token");
-            return Ok(Response::new_error(404, "This account doesn't exist!".to_string()).into());
+            return Err(error::ErrorNotFound( "This account doesn't exist!".to_string()));
         }
     };
 
     if !user.verified {
-        return Ok(Response::new_error(
-            403,
-            "Account not verified! Check your E-Mails for a verification link".to_string(),
-        )
-        .into());
+        return Err(error::ErrorUnauthorized("Account not verified! Check your E-Mails for a verification link".to_string()));
     }
 
     let untis = match UntisClient::unsafe_init(
@@ -88,12 +85,12 @@ pub async fn get_timetable(
         Ok(u) => u,
         Err(e) => {
             if let Error::Reqwest(_) = e {
-                return Ok(Response::new_error(400, "You done fucked up".into()).into());
+                return Err(error::ErrorUnprocessableEntity( "You done fucked up"));
             } else if let Error::UntisError(body) = e {
-                return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &body).into());
+                return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &body));
             }
             else {
-                return Ok(Response::new_error(500, "Some mysterious guy done fucked up".into()).into());
+                return Err(error::ErrorInternalServerError( "Some mysterious guy done fucked up"));
             }
         }
     };
@@ -110,8 +107,8 @@ pub async fn get_timetable(
     let timetable = match untis.clone().get_timetable(TimetableParameter::default(untis, from, until), class_name).await {
         Ok(timetable) => timetable,
         Err(err) => {
-            return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &err.to_string()).into());
+            return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &err.to_string()).into());
         }
     };
-    Ok(Response::new_success(TimetableResponse { lessons: timetable }).into())
+    Ok(web::Json(TimetableResponse { lessons: timetable }))
 }
diff --git a/backend/src/api/get_timetable_serviceworker.rs b/backend/src/api/get_timetable_serviceworker.rs
index 6a00412..ca864a5 100644
--- a/backend/src/api/get_timetable_serviceworker.rs
+++ b/backend/src/api/get_timetable_serviceworker.rs
@@ -1,15 +1,15 @@
 use actix_identity::Identity;
-use actix_web::{web::{self}, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::{debug, error};
 use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use crate::{
-    api::response::Response, api_wrapper::{
+    api_wrapper::{
         untis_client::UntisClient, utils::{FormattedLesson, TimetableParameter}
     }, models::{
         model::{DBConnection, CRUD}, user_model::User
-    }, prelude::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
+    }, error::Error, utils::time::{format_for_untis, get_this_friday, get_this_monday}, GlobalUntisData
 };
 
 #[derive(Serialize)]
@@ -34,12 +34,12 @@ pub async fn get_timetable_serviceworker(
     db: web::Data<DBConnection>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".to_string())));
+        return Err(error::ErrorForbidden( "Not logged in").into());
     }
 
     let jsessionid = match data.jsessionid.clone() {
         Some(session_cookie) => session_cookie,
-        None => return Ok(Response::new_error(403, "No JSESSIONID provided".to_string()).into()),
+        None => return Err(error::ErrorForbidden( "No JSESSIONID provided".to_string()).into()),
     };
 
     let pot_user: Option<User> = User::get_from_id(
@@ -51,12 +51,12 @@ pub async fn get_timetable_serviceworker(
                     Thing::from(split.unwrap())
                 } else {
                     error!("ID in session_cookie is wrong???");
-                    return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                    return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
                 }
             }
             Err(e) => {
                 error!("Error getting Identity id\n{e}");
-                return Ok(Response::new_error(500, "There was an error trying to get your id".to_string()).into());
+                return Err(error::ErrorInternalServerError( "There was an error trying to get your id".to_string()).into());
             }
         },
     )
@@ -66,15 +66,12 @@ pub async fn get_timetable_serviceworker(
         Some(u) => u,
         None => {
             debug!("Deleted(?) User tried to log in with old session token");
-            return Ok(Response::new_error(404, "This account doesn't exist!".to_string()).into());
+            return Err(error::ErrorNotFound( "This account doesn't exist!".to_string()).into());
         }
     };
 
     if !user.verified {
-        return Ok(Response::new_error(
-            403,
-            "Account not verified! Check your E-Mails for a verification link".to_string(),
-        )
+        return Err(error::ErrorForbidden("Account not verified! Check your E-Mails for a verification link".to_string(),)
         .into());
     }
 
@@ -92,12 +89,12 @@ pub async fn get_timetable_serviceworker(
         Ok(u) => u,
         Err(e) => {
             if let Error::Reqwest(_) = e {
-                return Ok(Response::new_error(400, "You done fucked up".into()).into());
+                return Err(error::ErrorUnprocessableEntity( "You done fucked up"));
             } else if let Error::UntisError(body) = e {
-                return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &body).into());
+                return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &body).into());
             }
             else {
-                return Ok(Response::new_error(500, "Some mysterious guy done fucked up".into()).into());
+                return Err(error::ErrorInternalServerError( "Some mysterious guy done fucked up"));
             }
         }
     };
@@ -114,8 +111,8 @@ pub async fn get_timetable_serviceworker(
     let timetable = match untis.clone().get_timetable(TimetableParameter::default(untis, from, until), class_name).await {
         Ok(timetable) => timetable,
         Err(err) => {
-            return Ok(Response::new_error(500, "Untis done fucked up ".to_string() + &err.to_string()).into());
+            return Err(error::ErrorInternalServerError( "Untis done fucked up ".to_string() + &err.to_string()).into());
         }
     };
-    Ok(Response::new_success(TimetableResponse { lessons: timetable }).into())
-}
+    Ok(web::Json(TimetableResponse { lessons: timetable }).into())
+}
\ No newline at end of file
diff --git a/backend/src/api/link/check_uuid.rs b/backend/src/api/link/check_uuid.rs
index 5007bcb..dd78f62 100644
--- a/backend/src/api/link/check_uuid.rs
+++ b/backend/src/api/link/check_uuid.rs
@@ -1,13 +1,13 @@
 use std::str::FromStr;
 
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::{error, warn};
 use serde::Deserialize;
 use surrealdb::sql::Thing;
 use uuid::Uuid;
 
 use crate::{
-    api::response::Response, internalError, models::{
+    api_wrapper::utils::TextResponse, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}
     }
 };
@@ -23,7 +23,7 @@ pub async fn check_uuid_get(
     path: web::Path<String>, typequery: web::Query<UuidQuery>, db: ConnectionData,
 ) -> Result<impl Responder> {
     if Uuid::from_str(&path).is_err() {
-        return Ok(Response::new_error(400, "UUID is not a valid uuid".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "UUID is not a valid uuid"));
     }
 
     let pot_link = match Link::get_from_id(
@@ -38,20 +38,20 @@ pub async fn check_uuid_get(
         Ok(a) => a,
         Err(e) => {
             error!("There was an error getting a link from the database\n{e}");
-            internalError!("There was a database error")
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if pot_link.is_none() {
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
     let link = pot_link.unwrap();
 
     if link.link_type != typequery.link_type {
         warn!("Link found but wrong type");
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
-    Ok(web::Json(Response::new_success("Link found".to_string())))
+    Ok(web::Json(TextResponse { message: "Link found".to_string()}))
 }
diff --git a/backend/src/api/link/email_change.rs b/backend/src/api/link/email_change.rs
index a475209..718fd93 100644
--- a/backend/src/api/link/email_change.rs
+++ b/backend/src/api/link/email_change.rs
@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use chrono::{Days, Utc};
 use lettre::{message::header::ContentType, Address};
 use log::{debug, error, warn};
@@ -9,7 +9,7 @@ use surrealdb::sql::Thing;
 use uuid::Uuid;
 
 use crate::{
-    api::response::Response, database::sessions::delete_user_sessions, mail::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
@@ -31,10 +31,10 @@ pub async fn email_change_post(
     path: web::Path<String>, body: web::Json<NewMail>, db: ConnectionData, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if body.mail.parse::<Address>().is_err() {
-        return Ok(web::Json(Response::new_error(400, "Not a valid e-mail".into())));
+        return Err(error::ErrorUnprocessableEntity( "Not a valid e-mail"));
     }
     if Uuid::from_str(&path).is_err() {
-        return Ok(Response::new_error(400, "UUID is not a valid uuid".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "UUID is not a valid uuid"));
     }
 
     let pot_link = match Link::get_from_id(
@@ -49,12 +49,12 @@ pub async fn email_change_post(
         Ok(a) => a,
         Err(e) => {
             error!("There was an error getting a link from the database\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     if pot_link.is_none() {
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
     let link = pot_link.unwrap();
@@ -65,7 +65,7 @@ pub async fn email_change_post(
             // Potential Attacker really shouldn't know if there's a link of another type with the
             // provided UUID
             warn!("Link found but wrong type");
-            return Ok(Response::new_error(404, "Link not found".into()).into());
+            return Err(error::ErrorNotFound( "Link not found"));
         }
     }
 
@@ -76,29 +76,29 @@ pub async fn email_change_post(
             Some(a) => a,
             None => {
                 error!("User ID in link is not valid");
-                return Ok(Response::new_error(500, "There was a database error".into()).into());
+                return Err(error::ErrorInternalServerError( "There was a database error"));
             }
         },
         Err(e) => {
             error!("Database error trying to get user from link\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     if user.verify_password(body.password.clone()).is_err() {
         debug!("Client sent wrong password");
-        return Ok(Response::new_error(403, "Wrong Password".into()).into());
+        return Err(error::ErrorForbidden( "Wrong Password"));
     };
 
     if match User::get_from_email(db.clone(), body.mail.clone()).await {
         Ok(a) => a.is_some(),
         Err(e) => {
             error!("Getting potential user from mail failed\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     } {
         warn!("E-mail is already in use");
-        return Ok(Response::new_error(403, "Mail already in use".into()).into());
+        return Err(error::ErrorForbidden( "Mail already in use"));
     }
 
     let new_user = User {
@@ -112,7 +112,7 @@ pub async fn email_change_post(
 
     if let Err(e) = User::update_replace(db.clone(), user_id.clone(), new_user).await {
         error!("Error updating user email\n{e}");
-        return Ok(Response::new_error(500, "There was a database error".into()).into());
+        return Err(error::ErrorInternalServerError( "There was a database error"));
     }
 
     if let Err(e) = Link::delete(db.clone(), link.id).await {
@@ -124,19 +124,19 @@ pub async fn email_change_post(
             Some(a) => a,
             None => {
                 error!("Updated e-mail isn't found in the database?");
-                return Ok(Response::new_error(500, "There was a database error".into()).into());
+                return Err(error::ErrorInternalServerError( "There was a database error"));
             }
         },
         Err(e) => {
             error!("Error trying to get updated user from database\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     // Logout user from all devices
     if let Err(e) = delete_user_sessions(db.clone(), user_id.to_string()).await {
         error!("Error deleting user sessions\n{e}");
-        return Ok(Response::new_error(500, "There was a database error".into()).into());
+        return Err(error::ErrorInternalServerError( "There was a database error"));
     };
 
     let expiry = Utc::now().checked_add_days(Days::new(2)).unwrap();
@@ -145,7 +145,7 @@ pub async fn email_change_post(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating reset link\n{e}");
-            return Ok(Response::new_error(500, "There was an error sending out an e-mail".into()).into());
+            return Err(error::ErrorInternalServerError( "There was an error sending out an e-mail"));
         }
     };
 
@@ -153,7 +153,7 @@ pub async fn email_change_post(
         Ok(a) => a.replace("${{RESET_URL}}", &reset_link).replace("${{NEW_MAIL}}", &body.mail),
         Err(e) => {
             error!("Error loading mail template\n{e}");
-            return Ok(Response::new_error(500, "There was an error sending out an e-mail".into()).into());
+            return Err(error::ErrorInternalServerError( "There was an error sending out an e-mail"));
         }
     };
 
@@ -162,7 +162,7 @@ pub async fn email_change_post(
             Ok(a) => a,
             Err(e) => {
                 error!("Error constructing message\n{e}");
-                return Ok(Response::new_error(500, "There was an error sending out an e-mail".into()).into());
+                return Err(error::ErrorInternalServerError( "There was an error sending out an e-mail"));
             }
         };
 
@@ -170,9 +170,9 @@ pub async fn email_change_post(
         Ok(_) => {}
         Err(e) => {
             error!("Error sending mail\n{e}");
-            return Ok(Response::new_error(500, "There was an error sending out an e-mail".into()).into());
+            return Err(error::ErrorInternalServerError( "There was an error sending out an e-mail"));
         }
     };
 
-    Ok(web::Json(Response::new_success("Successfully updated e-mail".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully updated e-mail".to_string()}))
 }
diff --git a/backend/src/api/link/email_reset.rs b/backend/src/api/link/email_reset.rs
index b7751e1..d14ace9 100644
--- a/backend/src/api/link/email_reset.rs
+++ b/backend/src/api/link/email_reset.rs
@@ -1,6 +1,6 @@
 use std::str::FromStr;
 
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use lettre::Address;
 use log::{error, warn};
 use serde::Deserialize;
@@ -8,7 +8,7 @@ use surrealdb::sql::Thing;
 use uuid::Uuid;
 
 use crate::{
-    api::response::Response, database::sessions::delete_user_sessions, models::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
     }
 };
@@ -23,10 +23,10 @@ pub async fn email_reset_post(
     path: web::Path<String>, body: web::Json<NewMail>, db: ConnectionData,
 ) -> Result<impl Responder> {
     if body.mail.parse::<Address>().is_err() {
-        return Ok(web::Json(Response::new_error(400, "Not a valid e-mail".into())));
+        return Err(error::ErrorUnprocessableEntity( "Not a valid e-mail"));
     }
     if Uuid::from_str(&path).is_err() {
-        return Ok(Response::new_error(400, "UUID is not a valid uuid".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "UUID is not a valid uuid"));
     }
 
     let pot_link = match Link::get_from_id(
@@ -41,12 +41,12 @@ pub async fn email_reset_post(
         Ok(a) => a,
         Err(e) => {
             error!("There was an error getting a link from the database\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     if pot_link.is_none() {
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
     let link = pot_link.unwrap();
@@ -57,7 +57,7 @@ pub async fn email_reset_post(
             // Potential Attacker really shouldn't know if there's a link of another type with the
             // provided UUID
             warn!("Link found but wrong type");
-            return Ok(Response::new_error(404, "Link not found".into()).into());
+            return Err(error::ErrorNotFound( "Link not found"));
         }
     }
 
@@ -68,12 +68,12 @@ pub async fn email_reset_post(
             Some(a) => a,
             None => {
                 error!("User ID in link is not valid");
-                return Ok(Response::new_error(500, "There was a database error".into()).into());
+                return Err(error::ErrorInternalServerError( "There was a database error"));
             }
         },
         Err(e) => {
             error!("Database error trying to get user from link\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
@@ -81,11 +81,11 @@ pub async fn email_reset_post(
         Ok(a) => a.is_some(),
         Err(e) => {
             error!("Getting potential user from mail failed\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     } {
         warn!("E-mail is already in use");
-        return Ok(Response::new_error(403, "Mail already in use".into()).into());
+        return Err(error::ErrorForbidden( "Mail already in use"));
     }
 
     let new_user = User {
@@ -99,7 +99,7 @@ pub async fn email_reset_post(
 
     if User::update_replace(db.clone(), user_id.clone(), new_user).await.is_err() {
         error!("Error updating user email");
-        return Ok(Response::new_error(500, "There was a database error".into()).into());
+        return Err(error::ErrorInternalServerError( "There was a database error"));
     }
 
     if let Err(e) = Link::delete(db.clone(), link.id).await {
@@ -109,8 +109,8 @@ pub async fn email_reset_post(
     // Logout user from all devices
     if let Err(e) = delete_user_sessions(db.clone(), user_id.to_string()).await {
         error!("Error deleting user sessions\n{e}");
-        return Ok(Response::new_error(500, "There was a database error".into()).into());
+        return Err(error::ErrorInternalServerError( "There was a database error"));
     };
 
-    Ok(web::Json(Response::new_success("Successfully updated e-mail".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully updated e-mail".to_string()}))
 }
diff --git a/backend/src/api/link/password.rs b/backend/src/api/link/password.rs
index 8ef2744..f80d6f4 100644
--- a/backend/src/api/link/password.rs
+++ b/backend/src/api/link/password.rs
@@ -4,7 +4,7 @@
 // 3. Passwort über link in E-Mail zurücksetzen: /link/password/{uuid}
 use std::str::FromStr;
 
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
 use log::{error, warn};
 use rand_core::OsRng;
@@ -13,9 +13,9 @@ use surrealdb::sql::Thing;
 use uuid::Uuid;
 
 use crate::{
-    api::response::Response, database::sessions::delete_user_sessions, models::{
+    api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, error::Error, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
-    }, prelude::Error, utils::password::valid_password
+    }, utils::password::valid_password
 };
 
 #[derive(Debug, Deserialize)]
@@ -30,7 +30,7 @@ pub async fn reset_password_post(
     path: web::Path<String>, db: ConnectionData, body: web::Json<PasswordChange>,
 ) -> Result<impl Responder> {
     if Uuid::from_str(&path).is_err() {
-        return Ok(Response::new_error(400, "UUID is not a valid uuid".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "UUID is not a valid uuid"));
     }
     if let Err(e) = valid_password(&body.new_password) {
         return Err(Error::from(e).into());
@@ -48,12 +48,12 @@ pub async fn reset_password_post(
         Ok(a) => a,
         Err(e) => {
             error!("There was an error getting a link from the database\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     if pot_link.is_none() {
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
     let link = pot_link.unwrap();
@@ -64,7 +64,7 @@ pub async fn reset_password_post(
             // Potential Attacker really shouldn't know if there's a link of another type with the
             // provided UUID
             warn!("Link found but wrong type");
-            return Ok(Response::new_error(404, "Link not found".into()).into());
+            return Err(error::ErrorNotFound( "Link not found"));
         }
     }
 
@@ -75,19 +75,19 @@ pub async fn reset_password_post(
             Some(a) => a,
             None => {
                 error!("User ID in link is not valid");
-                return Ok(Response::new_error(500, "There was a database error".into()).into());
+                return Err(error::ErrorInternalServerError( "There was a database error"));
             }
         },
         Err(e) => {
             error!("Database error trying to get user from link\n{e}");
-            return Ok(Response::new_error(500, "There was a database error".into()).into());
+            return Err(error::ErrorInternalServerError( "There was a database error"));
         }
     };
 
     let argon2 = Argon2::default();
 
     if user.verify_password(body.new_password.clone()).is_ok() {
-        return Ok(Response::new_error(400, "New Password can't be Old Password".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "New Password can't be Old Password"));
     }
 
     let salt = SaltString::generate(OsRng);
@@ -95,7 +95,7 @@ pub async fn reset_password_post(
         Ok(a) => a.to_string(),
         Err(e) => {
             error!("Error trying to hash password\n{e}");
-            return Ok(Response::new_error(500, "Unknown error trying to hash password".to_string()).into());
+            return Err(error::ErrorInternalServerError( "Unknown error trying to hash password".to_string()).into());
         }
     };
 
@@ -111,7 +111,7 @@ pub async fn reset_password_post(
 
     if let Err(e) = User::update_replace(db.clone(), new_user.clone().id, new_user.clone()).await {
         error!("Error updating user\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     }
 
     if let Err(e) = Link::delete(db.clone(), link.id).await {
@@ -120,8 +120,8 @@ pub async fn reset_password_post(
 
     if let Err(e) = delete_user_sessions(db.clone(), new_user.id.to_string()).await {
         error!("Error logging user out\n{e}");
-        return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+        return Err(error::ErrorInternalServerError( "Internal Server Error"));
     }
 
-    Ok(web::Json(Response::new_success("Successfully updated Password".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully updated Password".to_string()}))
 }
diff --git a/backend/src/api/link/verify.rs b/backend/src/api/link/verify.rs
index 52234a4..d3aa2ed 100644
--- a/backend/src/api/link/verify.rs
+++ b/backend/src/api/link/verify.rs
@@ -1,12 +1,12 @@
 use std::str::FromStr;
 
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::{error, warn};
 use surrealdb::sql::Thing;
 use uuid::Uuid;
 
 use crate::{
-    api::response::Response, internalError, models::{
+    api_wrapper::utils::TextResponse, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
     }
 };
@@ -14,7 +14,7 @@ use crate::{
 
 pub async fn verify_get(path: web::Path<String>, db: ConnectionData) -> Result<impl Responder> {
     if Uuid::from_str(&path).is_err() {
-        return Ok(web::Json(Response::new_error(400, "UUID is not a valid uuid".into())));
+        return Err(error::ErrorUnprocessableEntity( "UUID is not a valid uuid"));
     }
 
     let pot_link = match Link::get_from_id(
@@ -29,12 +29,12 @@ pub async fn verify_get(path: web::Path<String>, db: ConnectionData) -> Result<i
         Ok(a) => a,
         Err(e) => {
             error!("There was an error getting a link from the database\n{e}");
-            internalError!("There was a database error")
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if pot_link.is_none() {
-        return Ok(Response::new_error(404, "Link not found".into()).into());
+        return Err(error::ErrorNotFound( "Link not found"));
     }
 
     let link = pot_link.unwrap();
@@ -45,7 +45,7 @@ pub async fn verify_get(path: web::Path<String>, db: ConnectionData) -> Result<i
             // Potential Attacker really shouldn't know if there's a link of another type with the
             // provided UUID
             warn!("Link found but wrong type");
-            return Ok(Response::new_error(404, "Link not found".into()).into());
+            return Err(error::ErrorNotFound( "Link not found"));
         }
     }
 
@@ -54,12 +54,12 @@ pub async fn verify_get(path: web::Path<String>, db: ConnectionData) -> Result<i
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error getting user from id\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -74,12 +74,12 @@ pub async fn verify_get(path: web::Path<String>, db: ConnectionData) -> Result<i
 
     if let Err(e) = User::update_replace(db.clone(), link.user, new_user).await {
         error!("Updating user failed\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     }
 
     if let Err(e) = Link::delete(db, link.id).await {
         warn!("Failed to delete link, ignoring\n{e}");
     }
 
-    Ok(web::Json(Response::new_success("Successfully verified!".to_string())))
+    Ok(web::Json(TextResponse { message: "Successfully verified!".to_string()}))
 }
diff --git a/backend/src/api/login.rs b/backend/src/api/login.rs
index 7dfbe37..35405b5 100644
--- a/backend/src/api/login.rs
+++ b/backend/src/api/login.rs
@@ -1,9 +1,8 @@
 use actix_identity::Identity;
-use actix_web::{web, HttpMessage, HttpRequest, Responder, Result};
+use actix_web::{error, web, HttpMessage, HttpRequest, Responder, Result};
 use log::error;
 use serde::{Deserialize, Serialize};
 
-use super::response::Response;
 use crate::models::{model::DBConnection, user_model::User};
 
 #[derive(Deserialize)]
@@ -26,27 +25,26 @@ pub async fn login_post(
             Ok(n) => n,
             Err(e) => {
                 error!("Unknown error occured when trying to get user.\n{}", e);
-                return Ok(web::Json(Response::new_error(500, "Internal Server Error".to_owned())));
+                return Err(error::ErrorInternalServerError( "Internal Server Error".to_owned()));
             }
         } {
             Some(u) => u,
             None => {
-                return Ok(Response::new_error(403, "E-Mail or Password is incorrect!".to_owned()).into());
+                return Err(error::ErrorForbidden( "E-Mail or Password is incorrect!".to_owned()).into());
             }
         }
     };
 
     match db_user.verify_password(data.password.clone()) {
         Ok(_) => match Identity::login(&req.extensions(), db_user.id.to_string()) {
-            Ok(_) => Ok(Response::<LoginResponse>::new_success(LoginResponse {
+            Ok(_) => Ok(web::Json(LoginResponse {
                 untis_cypher: db_user.untis_cypher,
-            })
-            .into()),
+            })),
             Err(e) => {
                 error!("Error: Unknown error trying to login to Identity\n{}", e);
-                Ok(Response::new_error(500, "Internal Server Error".to_owned()).into())
+                Err(error::ErrorInternalServerError( "Internal Server Error".to_owned()).into())
             }
         },
-        Err(_) => Ok(Response::new_error(403, "E-Mail or Password is incorrect!".to_owned()).into()),
+        Err(_) => Err(error::ErrorForbidden( "E-Mail or Password is incorrect!".to_owned()).into()),
     }
 }
diff --git a/backend/src/api/logout.rs b/backend/src/api/logout.rs
index 634148e..8b731c3 100644
--- a/backend/src/api/logout.rs
+++ b/backend/src/api/logout.rs
@@ -1,13 +1,14 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
+
+use crate::api_wrapper::utils::TextResponse;
 
-use super::response::Response;
 
 pub async fn logout_post(id: Option<Identity>) -> Result<impl Responder> {
     if let Some(id) = id {
         id.logout();
-        Ok(Response::new_success("Logout successful!").into())
+        Ok(web::Json(TextResponse { message: "Logout successful!".to_string()}))
     } else {
-        Ok(web::Json(Response::new_error(403, "Not logged in!".into())))
+        Err(error::ErrorForbidden( "Not logged in!"))
     } 
 }
diff --git a/backend/src/api/logout_all.rs b/backend/src/api/logout_all.rs
index 5f4925c..0041b6f 100644
--- a/backend/src/api/logout_all.rs
+++ b/backend/src/api/logout_all.rs
@@ -1,9 +1,8 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::error;
 
-use super::response::Response;
-use crate::{database::sessions::delete_user_sessions, models::model::DBConnection};
+use crate::{api_wrapper::utils::TextResponse, database::sessions::delete_user_sessions, models::model::DBConnection};
 
 pub async fn logout_all_post(id: Option<Identity>, db: web::Data<DBConnection>) -> Result<impl Responder> {
     if let Some(identity) = id {
@@ -11,12 +10,12 @@ pub async fn logout_all_post(id: Option<Identity>, db: web::Data<DBConnection>)
             Ok(a) => a,
             Err(e) => {
                 error!("There was an error trying to get id.id()\n{e}");
-                return Ok(Response::new_error(500, "Internal Server Error".into()).into());
+                return Err(error::ErrorInternalServerError( "Internal Server Error"));
             }
         };
         delete_user_sessions(db, id).await?;
-        Ok(Response::new_success("Logged out on all devices!").into())
+        Ok(web::Json(TextResponse { message: "Logged out on all devices!".to_string()}))
     } else {
-        Ok(web::Json(Response::new_error(403, "Not logged in!".into())))
+        Err(error::ErrorForbidden( "Not logged in!"))
     } 
 }
diff --git a/backend/src/api/mod.rs b/backend/src/api/mod.rs
index 6806f29..3521d8b 100644
--- a/backend/src/api/mod.rs
+++ b/backend/src/api/mod.rs
@@ -14,6 +14,5 @@ pub mod logout;
 pub mod logout_all;
 pub mod register;
 pub mod resend_mail;
-pub mod response;
 pub mod verified;
-pub mod get_timetable_serviceworker;
\ No newline at end of file
+//pub mod get_timetable_serviceworker;
\ No newline at end of file
diff --git a/backend/src/api/register.rs b/backend/src/api/register.rs
index fe9a9c1..5874555 100644
--- a/backend/src/api/register.rs
+++ b/backend/src/api/register.rs
@@ -1,5 +1,5 @@
 use actix_identity::Identity;
-use actix_web::{web, HttpMessage, HttpRequest, Responder, Result};
+use actix_web::{error, web, HttpMessage, HttpRequest, Responder, Result};
 use argon2::{password_hash::SaltString, Argon2, PasswordHasher};
 use chrono::{Months, Utc};
 use lettre::{message::header::ContentType, Address};
@@ -8,11 +8,11 @@ use rand_core::OsRng;
 use serde::Deserialize;
 
 use crate::{
-    api::response::Response, internalError, mail::{
+    api_wrapper::utils::TextResponse, error::Error, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::{DBConnection, CRUD}, user_model::{User, UserCreate}
-    }, prelude::Error, utils::password::valid_password
+    }, utils::password::valid_password
 };
 
 #[derive(Deserialize)]
@@ -27,12 +27,12 @@ pub async fn register_post(
     data: web::Json<RegisterData>, db: web::Data<DBConnection>, request: HttpRequest, mailer: web::Data<Mailer>,
 ) -> Result<impl Responder> {
     if data.email.clone().parse::<Address>().is_err() {
-        return Ok(Response::new_error(400, "Not a valid email address".into()).into());
+        return Err(error::ErrorUnprocessableEntity( "Not a valid email address"));
     }
 
     let pot_user = User::get_from_email(db.clone(), data.email.clone()).await;
     if pot_user.is_ok() && pot_user.unwrap().is_some() {
-        return Ok(web::Json(Response::new_error(403, "E-mail already associated to account!".to_string())));
+        return Err(error::ErrorForbidden( "E-mail already associated to account!".to_string()));
     }
     if let Err(e) = valid_password(&data.password) {
         return Err(Error::from(e).into());
@@ -45,7 +45,7 @@ pub async fn register_post(
         Ok(str) => str.to_string(),
         Err(e) => {
             error!("Error: Unknown error trying to hash password\n{}", e);
-            internalError!("Error trying to hash password")
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -68,7 +68,7 @@ pub async fn register_post(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating link\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -76,7 +76,7 @@ pub async fn register_post(
         Ok(a) => a.replace("${{VERIFY_URL}}", &link),
         Err(e) => {
             error!("Error loading template\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -85,19 +85,19 @@ pub async fn register_post(
 
         Err(e) => {
             error!("Error building message\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     }
 
     if let Err(e) = Identity::login(&request.extensions(), ret_user.id.to_string()) {
         error!("Error trying to log into Identity\n{}", e);
-        internalError!("Error trying to log in, please try again")
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     };
 
-    Ok(Response::new_success("Account successfully registered".to_string()).into())
+    Ok(web::Json(TextResponse { message: "Account successfully registered".to_string()}))
 }
diff --git a/backend/src/api/resend_mail.rs b/backend/src/api/resend_mail.rs
index b2222dc..da71b09 100644
--- a/backend/src/api/resend_mail.rs
+++ b/backend/src/api/resend_mail.rs
@@ -1,13 +1,12 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use chrono::{Months, Utc};
 use lettre::message::header::ContentType;
 use log::error;
 use surrealdb::sql::Thing;
 
-use super::response::Response;
 use crate::{
-    internalError, mail::{
+    api_wrapper::utils::TextResponse, mail::{
         mailing::{build_mail, send_mail}, utils::{load_template, Mailer}
     }, models::{
         links_model::{Link, LinkType}, model::{ConnectionData, CRUD}, user_model::User
@@ -19,7 +18,7 @@ pub async fn resend_mail_get(
     db: ConnectionData, mailer: web::Data<Mailer>, id: Option<Identity>,
 ) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in".to_string())));
+        return Err(error::ErrorForbidden( "Not logged in".to_string()));
     }
 
     let id = id.unwrap();
@@ -27,7 +26,7 @@ pub async fn resend_mail_get(
         Ok(a) => Thing::from(a.split_once(':').unwrap()),
         Err(e) => {
             error!("Error trying to get id\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -36,22 +35,22 @@ pub async fn resend_mail_get(
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error trying to get user\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if user.clone().verified {
-        return Ok(web::Json(Response::new_error(400, "You're already verified".to_string())));
+        return Err(error::ErrorUnprocessableEntity( "You're already verified".to_string()));
     }
 
     if let Err(e) = Link::delete_from_user_type(db.clone(), user.clone(), LinkType::VerifyAccount).await {
         error!("Error deleting verification links\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     }
 
     let expiry_time = Utc::now().checked_add_months(Months::new(1)).unwrap();
@@ -60,7 +59,7 @@ pub async fn resend_mail_get(
         Ok(a) => a.construct_link(),
         Err(e) => {
             error!("Error creating link\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -68,7 +67,7 @@ pub async fn resend_mail_get(
         Ok(a) => a.replace("${{VERIFY_URL}}", &link),
         Err(e) => {
             error!("Error loading template\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -76,14 +75,14 @@ pub async fn resend_mail_get(
         Ok(a) => a,
         Err(e) => {
             error!("Error building message\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
     if let Err(e) = send_mail(mailer, message).await {
         error!("Error sending mail\n{e}");
-        internalError!()
+        return Err(error::ErrorInternalServerError("Internal Server Error"));
     }
 
-    Ok(web::Json(Response::new_success("Sent E-Mail, check your inbox".to_string())))
+    Ok(web::Json(TextResponse { message: "Sent E-Mail, check your inbox".to_string()}))
 }
diff --git a/backend/src/api/response.rs b/backend/src/api/response.rs
deleted file mode 100644
index c735cc1..0000000
--- a/backend/src/api/response.rs
+++ /dev/null
@@ -1,65 +0,0 @@
-use actix_web::{web::Json, ResponseError as actixResponseError};
-use serde::Serialize;
-
-use crate::prelude::Error;
-
-#[derive(Serialize)]
-pub struct Response<T> {
-    pub success: bool,
-    pub body: ResponseResult<T>,
-}
-
-impl<ResponseError> Response<ResponseError> {
-    pub fn new_error(code: u16, message: String) -> Self {
-        Self {
-            success: false,
-            body: ResponseResult::Err(crate::api::response::ResponseError { code, message }),
-        }
-    }
-}
-
-impl<ResponseError> From<Error> for Response<ResponseError> {
-    fn from(value: Error) -> Self {
-        Response {
-            success: false,
-            body: ResponseResult::Err(value.into()),
-        }
-    }
-}
-
-impl<T> Response<T> {
-    pub fn new_success(body: T) -> Self {
-        Self {
-            success: true,
-            body: ResponseResult::Ok(body),
-        }
-    }
-}
-
-impl<T> From<Response<T>> for Json<Response<T>> {
-    fn from(val: Response<T>) -> Self {
-        Json(val)
-    }
-}
-
-#[derive(Serialize)]
-#[serde(untagged)]
-pub enum ResponseResult<T> {
-    Ok(T),
-    Err(ResponseError),
-}
-
-#[derive(Serialize)]
-pub struct ResponseError {
-    code: u16,
-    message: String,
-}
-
-impl From<Error> for ResponseError {
-    fn from(value: Error) -> Self {
-        Self {
-            code: value.status_code().into(),
-            message: value.to_string(),
-        }
-    }
-}
diff --git a/backend/src/api/verified.rs b/backend/src/api/verified.rs
index dd46981..8868030 100644
--- a/backend/src/api/verified.rs
+++ b/backend/src/api/verified.rs
@@ -1,25 +1,22 @@
 use actix_identity::Identity;
-use actix_web::{web, Responder, Result};
+use actix_web::{error, web, Responder, Result};
 use log::error;
 use surrealdb::sql::Thing;
 
-use super::response::Response;
-use crate::{
-    internalError, models::{
+use crate::models::{
         model::{ConnectionData, CRUD}, user_model::User
-    }
-};
+    };
 
 pub async fn verified_get(id: Option<Identity>, db: ConnectionData) -> Result<impl Responder> {
     if id.is_none() {
-        return Ok(web::Json(Response::new_error(403, "Not logged in!".to_string())));
+        return Err(error::ErrorForbidden( "Not logged in!".to_string()));
     }
 
     let id = match id.unwrap().id() {
         Ok(a) => Thing::from(a.split_once(':').unwrap()),
         Err(e) => {
             error!("Error getting id.id()\n{e}");
-            internalError!()
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
@@ -28,14 +25,14 @@ pub async fn verified_get(id: Option<Identity>, db: ConnectionData) -> Result<im
             Some(a) => a,
             None => {
                 error!("User not found?");
-                internalError!()
+                return Err(error::ErrorInternalServerError("Internal Server Error"));
             }
         },
         Err(e) => {
             error!("Error getting user from id\n{e}");
-            internalError!("There was a database error")
+            return Err(error::ErrorInternalServerError("Internal Server Error"));
         }
     };
 
-    Ok(web::Json(Response::new_success(user.verified)))
+    Ok(web::Json(user.verified))
 }
diff --git a/backend/src/api_wrapper/untis_client.rs b/backend/src/api_wrapper/untis_client.rs
index 8b1bc52..111ea46 100644
--- a/backend/src/api_wrapper/untis_client.rs
+++ b/backend/src/api_wrapper/untis_client.rs
@@ -10,7 +10,7 @@ use super::utils::{
     self, day_of_week, DetailedSubject, FormattedFreeRoom, FormattedLesson, Holidays, Klasse, LoginResults, PeriodObject, Schoolyear, Substitution, TimegridUnits, TimetableParameter, UntisArrayResponse
 };
 use crate::{
-    api_wrapper::utils::UntisResponse, models::{manual_lb_model::ManualLB, model::DBConnection, room_model::Room, teacher_model::Teacher}, prelude::Error
+    api_wrapper::utils::UntisResponse, models::{manual_lb_model::ManualLB, model::DBConnection, room_model::Room, teacher_model::Teacher}, error::Error
 };
 
 #[derive(Clone)]
@@ -684,7 +684,7 @@ impl UntisClient {
 
         Ok(every_lb)
     }
-    /// .
+    /// 
     fn manual_overwrite_lbs(lb: &FormattedLesson) -> bool {
         matches! (
             (lb.day, lb.start, lb.teacher.as_str()),
diff --git a/backend/src/api_wrapper/utils.rs b/backend/src/api_wrapper/utils.rs
index c0a6c37..0c46499 100644
--- a/backend/src/api_wrapper/utils.rs
+++ b/backend/src/api_wrapper/utils.rs
@@ -328,3 +328,8 @@ pub fn day_of_week(date: u32) -> u8 {
     let h = (d + (13 * (m + 1)) / 5 + k + k / 4 + j / 4 + 5 * j) % 7;
     ((h + 5) % 7) as u8
 }
+
+#[derive(Serialize)]
+pub struct TextResponse {
+    pub message: String
+}
\ No newline at end of file
diff --git a/backend/src/database/sessions.rs b/backend/src/database/sessions.rs
index 0780f69..71ae787 100644
--- a/backend/src/database/sessions.rs
+++ b/backend/src/database/sessions.rs
@@ -1,4 +1,4 @@
-use crate::{models::model::ConnectionData, prelude::Error};
+use crate::{models::model::ConnectionData, error::Error};
 
 // This is very hacky but it works
 /// NEXER EXPOSE THIS FUNCTION TO USER INPUT, IT WILL ALLOW THEM TO SQL INJECT
diff --git a/backend/src/mail/mailing.rs b/backend/src/mail/mailing.rs
index 4e1395e..6dca44a 100644
--- a/backend/src/mail/mailing.rs
+++ b/backend/src/mail/mailing.rs
@@ -3,7 +3,7 @@ use lettre::{
 };
 
 use super::{error::MailError, utils::Mailer};
-use crate::prelude::Error;
+use crate::error::Error;
 
 pub fn build_mail<T>(to: &str, subject: &str, content_type: ContentType, body: T) -> Result<Message, Error>
 where
diff --git a/backend/src/main.rs b/backend/src/main.rs
index 9833e4d..7392f18 100644
--- a/backend/src/main.rs
+++ b/backend/src/main.rs
@@ -7,7 +7,6 @@ mod error;
 mod governor;
 mod mail;
 mod models;
-mod prelude;
 mod utils;
 
 use std::{
@@ -26,7 +25,7 @@ use actix_web::{
     cookie::{time::Duration, Key}, middleware::Logger, middleware::Compress, web::{self, Data}, App, HttpResponse, HttpServer
 };
 use api::{
-    change_email::change_email_get, get_free_rooms::get_free_rooms, get_timetable_serviceworker::get_timetable_serviceworker, change_password::change_password_post, change_untis_data::change_untis_data_post, check_session::check_session_get, delete::delete_post, forgot_password::forgot_password_post, gdpr_data_compliance::gdpr_data_compliance_get, get_lernbueros::get_lernbueros, get_timetable::get_timetable, link::{
+    change_email::change_email_get, get_free_rooms::get_free_rooms, /* get_timetable_serviceworker::get_timetable_serviceworker ,*/ change_password::change_password_post, change_untis_data::change_untis_data_post, check_session::check_session_get, delete::delete_post, forgot_password::forgot_password_post, gdpr_data_compliance::gdpr_data_compliance_get, get_lernbueros::get_lernbueros, get_timetable::get_timetable, link::{
         check_uuid::check_uuid_get, email_change::email_change_post, email_reset::email_reset_post, password::reset_password_post, verify::verify_get
     }, login::login_post, logout::logout_post, logout_all::logout_all_post, register::register_post, resend_mail::resend_mail_get, verified::verified_get
 };
@@ -160,7 +159,7 @@ async fn main() -> io::Result<()> {
         #[cfg(feature = "proxy")]
         let governor_config = GovernorConfigBuilder::default()
                 .key_extractor(NginxIpKeyExctrator)
-                .per_second(10)
+                .seconds_per_request(10)
                 .burst_size(20)
                 .use_headers()
                 .finish()
@@ -207,7 +206,7 @@ async fn main() -> io::Result<()> {
             .service(web::resource("/delete").route(web::post().to(delete_post)))
             .service(web::resource("/check_session").route(web::get().to(check_session_get)))
             .service(web::resource("/get_timetable").route(web::get().to(get_timetable)))
-            .service(web::resource("/get_timetable_serviceworker").route(web::post().to(get_timetable_serviceworker)))
+            //.service(web::resource("/get_timetable_serviceworker").route(web::post().to(get_timetable_serviceworker)))
             .service(web::resource("/get_lernbueros").route(web::get().to(get_lernbueros)))
             .service(web::resource("/get_free_rooms").route(web::get().to(get_free_rooms)))
             .service(web::resource("/change_email").route(web::get().to(change_email_get)))
diff --git a/backend/src/models/links_model.rs b/backend/src/models/links_model.rs
index e619c6d..ee643ac 100644
--- a/backend/src/models/links_model.rs
+++ b/backend/src/models/links_model.rs
@@ -6,7 +6,7 @@ use surrealdb::sql::{Id, Thing};
 use super::{
     model::{ConnectionData, DBConnection, CRUD}, user_model::User
 };
-use crate::{prelude::Error, utils::uuid::random_id};
+use crate::{error::Error, utils::uuid::random_id};
 
 #[derive(Debug, Serialize, Deserialize)]
 pub struct Link {
diff --git a/backend/src/models/manual_lb_model.rs b/backend/src/models/manual_lb_model.rs
index e4f164d..f4a7d88 100644
--- a/backend/src/models/manual_lb_model.rs
+++ b/backend/src/models/manual_lb_model.rs
@@ -1,7 +1,7 @@
 use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
-use crate::prelude::Error;
+use crate::error::Error;
 
 use super::model::{ConnectionData, DBConnection, CRUD};
 
diff --git a/backend/src/models/model.rs b/backend/src/models/model.rs
index c8cb917..083d962 100644
--- a/backend/src/models/model.rs
+++ b/backend/src/models/model.rs
@@ -2,7 +2,7 @@ use async_trait::async_trait;
 use serde::{Deserialize, Serialize};
 use surrealdb::{engine::remote::ws::Client, sql::Thing, Surreal};
 
-use crate::prelude::Error;
+use crate::error::Error;
 
 pub type DBConnection = Surreal<Client>;
 pub type ConnectionData = actix_web::web::Data<DBConnection>;
diff --git a/backend/src/models/room_model.rs b/backend/src/models/room_model.rs
index 0dcfd5e..78dc92f 100644
--- a/backend/src/models/room_model.rs
+++ b/backend/src/models/room_model.rs
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use super::model::{ConnectionData, DBConnection, CRUD};
-use crate::prelude::Error;
+use crate::error::Error;
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
 pub struct Room {
diff --git a/backend/src/models/sessions_model.rs b/backend/src/models/sessions_model.rs
index 2d07ad1..93d369b 100644
--- a/backend/src/models/sessions_model.rs
+++ b/backend/src/models/sessions_model.rs
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
 use surrealdb::sql::{Datetime, Thing};
 
 use super::model::ConnectionData;
-use crate::prelude::Error;
+use crate::error::Error;
 
 
 #[derive(Debug, Serialize, Deserialize)]
diff --git a/backend/src/models/teacher_model.rs b/backend/src/models/teacher_model.rs
index 9b1b510..f451aae 100644
--- a/backend/src/models/teacher_model.rs
+++ b/backend/src/models/teacher_model.rs
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
 use surrealdb::sql::{Array, Thing};
 
 use super::model::{ConnectionData, DBConnection, CRUD};
-use crate::prelude::Error;
+use crate::error::Error;
 
 #[derive(Debug, Serialize, Deserialize)]
 pub struct Teacher {
diff --git a/backend/src/models/user_model.rs b/backend/src/models/user_model.rs
index 4b000aa..4647fb9 100644
--- a/backend/src/models/user_model.rs
+++ b/backend/src/models/user_model.rs
@@ -3,7 +3,7 @@ use serde::{Deserialize, Serialize};
 use surrealdb::sql::Thing;
 
 use super::model::{ConnectionData, DBConnection, CRUD};
-use crate::prelude::Error;
+use crate::error::Error;
 
 #[derive(Debug, Serialize, Deserialize, Clone)]
 pub struct User {
diff --git a/backend/src/prelude.rs b/backend/src/prelude.rs
deleted file mode 100644
index 52f1303..0000000
--- a/backend/src/prelude.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-pub use crate::error::Error;
-
-/// Macro that returns a 500 Internal Server Error JSON Response
-/// Can take a string literal as an argument to change the error message
-///
-/// ## Usage
-/// ```no_run
-/// internalError!() // Returns a "Internal Server Error" with code 500
-/// internalError!("Database Error") // Returns a "Database Error" with code 500
-/// ```
-#[macro_export]
-macro_rules! internalError {
-    ($l:literal) => {{
-        return Ok(actix_web::web::Json($crate::api::response::Response::new_error(500, $l.to_string())));
-    }};
-    () => {{
-        return Ok(actix_web::web::Json($crate::api::response::Response::new_error(
-            500,
-            "Internal Server Error".to_string(),
-        )));
-    }};
-}
diff --git a/frontend/compileServiceWorker.ts b/frontend/compileServiceWorker.ts
index 00fe797..a09f71f 100644
--- a/frontend/compileServiceWorker.ts
+++ b/frontend/compileServiceWorker.ts
@@ -1,7 +1,6 @@
 import { rollup, InputOptions, OutputOptions } from "rollup";
 import typescript from "@rollup/plugin-typescript";
-import terser from "@rollup/plugin-terser"
-
+import terser from "@rollup/plugin-terser";
 
 const compileServiceWorker = () => ({
   name: "compile-typescript-service-worker",
@@ -17,7 +16,7 @@ const compileServiceWorker = () => ({
     };
     const bundle = await rollup(inputOptions);
     await bundle.write(outputOptions);
-    await bundle.close()
+    await bundle.close();
   }
 });
-export default compileServiceWorker
\ No newline at end of file
+export default compileServiceWorker;
diff --git a/frontend/public/manifest.webmanifest b/frontend/public/manifest.webmanifest
index 3f5053f..efb7e8b 100644
--- a/frontend/public/manifest.webmanifest
+++ b/frontend/public/manifest.webmanifest
@@ -8,7 +8,6 @@
   "background_color": "#24273a",
   "theme_color": "#24273a",
 
-    
   "icons": [
     {
       "src": "/AppImages/windows11/SmallTile.scale-100.png",
@@ -459,4 +458,4 @@
       "sizes": "1024x1024"
     }
   ]
-}
\ No newline at end of file
+}
diff --git a/frontend/src/api/dateHandling.ts b/frontend/src/api/dateHandling.ts
index d084841..563c84c 100644
--- a/frontend/src/api/dateHandling.ts
+++ b/frontend/src/api/dateHandling.ts
@@ -1,8 +1,8 @@
-export function getMondayAndFridayDates(strMonday? : string): { currentMonday: string; currentFriday: string } {
+export function getMondayAndFridayDates(strMonday?: string): { currentMonday: string; currentFriday: string } {
   let now = new Date();
   let currentDayOfWeek = now.getDay(); // 0 = Sunday, 1 = Monday, ..., 6 = Saturday
 
-  if(strMonday){
+  if (strMonday) {
     currentDayOfWeek = 0;
     now = createDate(strMonday);
   }
diff --git a/frontend/src/api/frontmatter.ts b/frontend/src/api/frontmatter.ts
index 183fd67..127c1aa 100644
--- a/frontend/src/api/frontmatter.ts
+++ b/frontend/src/api/frontmatter.ts
@@ -12,6 +12,9 @@ class Request {
         credentials: "include",
         body: JSON.stringify(data)
       });
+      if (!result.ok) {
+        return Promise.reject(result.status);
+      }
       if (!result.body) {
         return Promise.reject({ status: 500, message: "Server Connection Failed" });
       }
@@ -20,10 +23,7 @@ class Request {
       }
       let stream = await Request.readStream(result.body);
       let body = JSON.parse(stream);
-      if (!body.success) {
-        return Promise.reject(body.body);
-      }
-      return body.body;
+      return body;
     } catch (error) {
       return Promise.reject(error);
     }
@@ -36,14 +36,13 @@ class Request {
         method: "GET",
         credentials: "include"
       });
+      if (!result.ok) {
+        return Promise.reject(result.status);
+      }
       if (result.status == 429) {
         return Promise.reject(new Error("Too many requests. Try again later"));
       }
-      const body = await result.json();
-      if (!body.success) {
-        return Promise.reject(body.body);
-      }
-      return body.body;
+      return result.body;
     } catch (error) {
       return Promise.reject(error);
     }
@@ -65,6 +64,7 @@ class Request {
 export async function checkSessionIdAstro(id: string): Promise<any> {
   try {
     let result = await Request.Get("check_session", { Cookie: `id=${id}` });
+    console.log(result);
     return result;
   } catch (error) {
     return Promise.reject(error);
diff --git a/frontend/src/api/main.ts b/frontend/src/api/main.ts
index d8606ee..ce55f38 100644
--- a/frontend/src/api/main.ts
+++ b/frontend/src/api/main.ts
@@ -15,10 +15,10 @@ export interface TheScheduleObject {
   } | null;
 }
 export interface FreeRoom {
-  start: number,
-  length: number,
-  day: number,
-  room: string
+  start: number;
+  length: number;
+  day: number;
+  room: string;
 }
 export const SubjectColor: { [key: string]: string } = {
   M: "#dba402",
@@ -68,26 +68,25 @@ export function JSESSIONIDCookieString(JSESSIONID: string): string {
   return `JSESSIONID=${JSESSIONID}; max-age=600; secure; samesite=none; domain=${import.meta.env.PUBLIC_COOKIE_DOMAIN}`;
 }
 export async function getCommitHash(): Promise<string> {
-  const result = await fetch("https://api.github.com/repos/ixhbinphoenix/bne/commits/master", {
+  const result = (await fetch("https://api.github.com/repos/ixhbinphoenix/bne/commits/master", {
     method: "GET"
-  }) as unknown as Array<any>
+  })) as unknown as Array<any>;
   try {
-    return JSON.parse(await readStream(result.body)).sha.substring(0, 7)
-  }
-  catch (error) {
-    return Promise.reject(error)
+    return JSON.parse(await readStream(result.body)).sha.substring(0, 7);
+  } catch (error) {
+    return Promise.reject(error);
   }
 }
 async function readStream(stream: ReadableStream<Uint8Array>) {
-    const textDecode = new TextDecoder();
-    const chunks = [];
-    const reader = stream.getReader();
-    while (true) {
-      const { done, value } = await reader.read();
-      if (done) {
-        break;
-      }
-      chunks.push(textDecode.decode(value));
+  const textDecode = new TextDecoder();
+  const chunks = [];
+  const reader = stream.getReader();
+  while (true) {
+    const { done, value } = await reader.read();
+    if (done) {
+      break;
     }
-    return chunks.join("");
+    chunks.push(textDecode.decode(value));
+  }
+  return chunks.join("");
 }
diff --git a/frontend/src/api/theBackend.ts b/frontend/src/api/theBackend.ts
index 93ac9a6..3a1a1c3 100644
--- a/frontend/src/api/theBackend.ts
+++ b/frontend/src/api/theBackend.ts
@@ -15,18 +15,16 @@ class Request {
         credentials: "include",
         body: JSON.stringify(data)
       });
+      if (!result.ok) {
+        return Promise.reject({ status: result.status, message: await result.text() });
+      }
       if (!result.body) {
         return Promise.reject({ status: 500, message: "Server Connection Failed" });
       }
       if (result.status == 429) {
         return Promise.reject(new Error("Too many requests. Try again later"));
       }
-      let stream = await Request.readStream(result.body);
-      let body = JSON.parse(stream);
-      if (!body.success) {
-        return Promise.reject(body.body);
-      }
-      return body.body;
+      return result.json();
     } catch (error) {
       return Promise.reject(error);
     }
@@ -42,11 +40,10 @@ class Request {
       if (result.status == 429) {
         return Promise.reject(new Error("Too many requests. Try again later"));
       }
-      const body = await result.json();
-      if (!body.success) {
-        return Promise.reject(body.body);
+      if (result.headers.get("Content-Type") === "application/json") {
+        return await result.json();
       }
-      return body.body;
+      return await result.text();
     } catch (error) {
       return Promise.reject(error);
     }
@@ -104,7 +101,7 @@ export async function getTimetable(monday: string, friday: string, className?: s
     const untisCredentials = getLocalUntisCredentials();
     if (!storedJSessionId && getLocalUntisCredentials()) {
       const result = await fetchJSessionId(untisCredentials.username, untisCredentials.password);
-      document.cookie = JSESSIONIDCookieString(result.JSessionId) 
+      document.cookie = JSESSIONIDCookieString(result.JSessionId);
       body = await Request.Get<{ lessons: TheScheduleObject[] }>("get_timetable" + searchQuery);
     } else {
       body = await Request.Get<{ lessons: TheScheduleObject[] }>("get_timetable" + searchQuery);
@@ -114,7 +111,12 @@ export async function getTimetable(monday: string, friday: string, className?: s
     return Promise.reject(error);
   }
 }
-export async function getTimetableServiceWorker(monday: string, friday: string, JSessionId: string, className?: string): Promise<TheScheduleObject[]> {
+export async function getTimetableServiceWorker(
+  monday: string,
+  friday: string,
+  JSessionId: string,
+  className?: string
+): Promise<TheScheduleObject[]> {
   try {
     let body: { lessons: TheScheduleObject[] };
     let searchQuery = `?from=${monday}&until=${friday}`;
diff --git a/frontend/src/components/RegisterForm.tsx b/frontend/src/components/RegisterForm.tsx
index 7e07f31..f0f3b6d 100644
--- a/frontend/src/components/RegisterForm.tsx
+++ b/frontend/src/components/RegisterForm.tsx
@@ -20,7 +20,7 @@ export default function LoginForm(): JSX.Element {
     fetchJSessionId(event.target[3].value, event.target[4].value).then(
       (result) => {
         if (result.JSessionId && result.personId) {
-          document.cookie = JSESSIONIDCookieString(result.JSessionId); 
+          document.cookie = JSESSIONIDCookieString(result.JSessionId);
           sendRegister(
             event.target[0].value,
             event.target[1].value,
@@ -117,8 +117,17 @@ export default function LoginForm(): JSX.Element {
             required
           />
           <div class="checkbox-div">
-            <input type="checkbox" id="checkbox" required/>
-            <label htmlFor="checkbox">Ich akzeptiere die <a href="/datenschutz" style="color: var(--highlight-blue);">Datenschutzbestimmung</a> und <a href="/nutzungsbedingungen" style="color: var(--highlight-blue);">Nutzungsbedingungen</a></label>
+            <input type="checkbox" id="checkbox" required />
+            <label htmlFor="checkbox">
+              Ich akzeptiere die{" "}
+              <a href="/datenschutz" style="color: var(--highlight-blue);">
+                Datenschutzbestimmung
+              </a>{" "}
+              und{" "}
+              <a href="/nutzungsbedingungen" style="color: var(--highlight-blue);">
+                Nutzungsbedingungen
+              </a>
+            </label>
           </div>
           <div className="button-container">
             <input type="submit" id="submit-button" value="Absenden" />
diff --git a/frontend/src/components/plan-components/FreeRooms.tsx b/frontend/src/components/plan-components/FreeRooms.tsx
index ea10c3b..320854a 100644
--- a/frontend/src/components/plan-components/FreeRooms.tsx
+++ b/frontend/src/components/plan-components/FreeRooms.tsx
@@ -2,7 +2,7 @@
 
 import { JSESSIONIDCookieString, type FreeRoom } from "../../api/main";
 import { getFreeRooms } from "../../api/theBackend";
-import Loading from "../Loading"
+import Loading from "../Loading";
 import Popup from "./Popup";
 import type { JSX } from "preact";
 import "../../styles/Stundenplan.scss";
diff --git a/frontend/src/components/plan-components/Lernbueros.tsx b/frontend/src/components/plan-components/Lernbueros.tsx
index 8a30937..1bf6c5d 100644
--- a/frontend/src/components/plan-components/Lernbueros.tsx
+++ b/frontend/src/components/plan-components/Lernbueros.tsx
@@ -107,11 +107,10 @@ export default function Lernbueros(): JSX.Element {
         tableDaysTemp.push(<div className="table-day">{tableElements[i]}</div>);
       }
       setTableDays(tableDaysTemp);
-    }
-    else {
+    } else {
       openPopup();
     }
-  }
+  };
 
   useEffect(() => {
     onSwipe(".table-layout", { direction: "left" }, nextWeek);
@@ -304,21 +303,22 @@ export default function Lernbueros(): JSX.Element {
       const FilterItems = [];
       for (const item in SubjectNames) {
         if (item != "SP") {
-        FilterItems.push(
-          <label htmlFor={item}>
-            {SubjectNames[item]}
-            <input
-              type="checkbox"
-              id={item}
-              defaultChecked={filterItems[item]}
-              onClick={() => {
-                filterItems[item] = !filterItems[item];
-                changeFilter(filterItems);
-              }}
-            />
-            <span className="checkbox"></span>
-          </label>
-        );}
+          FilterItems.push(
+            <label htmlFor={item}>
+              {SubjectNames[item]}
+              <input
+                type="checkbox"
+                id={item}
+                defaultChecked={filterItems[item]}
+                onClick={() => {
+                  filterItems[item] = !filterItems[item];
+                  changeFilter(filterItems);
+                }}
+              />
+              <span className="checkbox"></span>
+            </label>
+          );
+        }
       }
       setFilterContent(
         <div class="filter-background">
@@ -421,7 +421,7 @@ export default function Lernbueros(): JSX.Element {
               }
               if (lessons[k].substitution?.cancelled) {
                 roomStyle = { textDecoration: "line-through" };
-                teacherStyle = { textDecoration: "line-through"};
+                teacherStyle = { textDecoration: "line-through" };
               }
               if (lessons[k].substitution?.substitution_text) {
                 substitutionTextStyle = { display: "block" };
diff --git a/frontend/src/components/plan-components/Settings.tsx b/frontend/src/components/plan-components/Settings.tsx
index fa1aab5..081ada0 100644
--- a/frontend/src/components/plan-components/Settings.tsx
+++ b/frontend/src/components/plan-components/Settings.tsx
@@ -76,11 +76,9 @@ export default function Settings(): JSX.Element {
   const [pageContent, setPageContent] = useState<JSX.Element>(Menu);
   const [username, setUsername] = useState("");
   useEffect(() => {
-    getCommitHash().then(
-      (result) => {
-        setCommitHash(result)
-      }
-    )
+    getCommitHash().then((result) => {
+      setCommitHash(result);
+    });
     showNotVerifiedMessage();
     const usernameRaw = localStorage.getItem("untis_username");
     const nameParts = usernameRaw?.split("_");
diff --git a/frontend/src/components/plan-components/Stundenplan.tsx b/frontend/src/components/plan-components/Stundenplan.tsx
index 72f8a8a..022f8e3 100644
--- a/frontend/src/components/plan-components/Stundenplan.tsx
+++ b/frontend/src/components/plan-components/Stundenplan.tsx
@@ -59,7 +59,7 @@ export default function Stundenplan(): JSX.Element {
         if (error.message == "Untis done fucked up Fetching from Untis failed") {
           fetchJSessionId(getLocalUntisCredentials().username, getLocalUntisCredentials().password).then((result) => {
             if (result.JSessionId) {
-              closePopup()
+              closePopup();
               document.cookie = JSESSIONIDCookieString(result.JSessionId);
               getTimetable(currentWeek.currentMonday, currentWeek.currentFriday).then(
                 (lessons) => {
@@ -196,7 +196,7 @@ export default function Stundenplan(): JSX.Element {
         if (error.message == "Untis done fucked up Fetching from Untis failed") {
           fetchJSessionId(getLocalUntisCredentials().username, getLocalUntisCredentials().password).then((result) => {
             if (result.JSessionId) {
-              document.cookie = JSESSIONIDCookieString(result.JSessionId)
+              document.cookie = JSESSIONIDCookieString(result.JSessionId);
               previousWeek();
             }
           });
diff --git a/frontend/src/components/plan-components/settings-components/ChangeEmail.tsx b/frontend/src/components/plan-components/settings-components/ChangeEmail.tsx
index 6616030..e58d054 100644
--- a/frontend/src/components/plan-components/settings-components/ChangeEmail.tsx
+++ b/frontend/src/components/plan-components/settings-components/ChangeEmail.tsx
@@ -17,6 +17,7 @@ export default function ChangeEmail(props: IProps): JSX.Element {
         setErrorMessage(<p>Deine E-Mail-Adresse wurde geändert</p>);
       },
       (error) => {
+        console.log(error);
         setErrorMessage(<p>Etwas ist schief gegangen: {error.message}</p>);
       }
     );
diff --git a/frontend/src/components/plan-components/settings-components/DeleteAccount.tsx b/frontend/src/components/plan-components/settings-components/DeleteAccount.tsx
index 06f2110..1561c50 100644
--- a/frontend/src/components/plan-components/settings-components/DeleteAccount.tsx
+++ b/frontend/src/components/plan-components/settings-components/DeleteAccount.tsx
@@ -39,4 +39,4 @@ export default function DeleteAccount(): JSX.Element {
       </div>
     </div>
   );
-}
\ No newline at end of file
+}
diff --git a/frontend/src/components/plan-components/settings-components/ResetEmail.tsx b/frontend/src/components/plan-components/settings-components/ResetEmail.tsx
index 3597bce..b5db811 100644
--- a/frontend/src/components/plan-components/settings-components/ResetEmail.tsx
+++ b/frontend/src/components/plan-components/settings-components/ResetEmail.tsx
@@ -17,7 +17,7 @@ export default function ResetEmail(props: IProps): JSX.Element {
         setErrorMessage(<p>Deine E-Mail-Adresse wurde geändert</p>);
       },
       (error) => {
-        setErrorMessage(<p>Etwas ist schief gelaufen: {error.message}</p>);
+        setErrorMessage(<p>Etwas ist schief gelaufen: {error}</p>);
       }
     );
   };
diff --git a/frontend/src/layouts/PlanLayout.astro b/frontend/src/layouts/PlanLayout.astro
index 9df8f5f..f69a971 100644
--- a/frontend/src/layouts/PlanLayout.astro
+++ b/frontend/src/layouts/PlanLayout.astro
@@ -13,18 +13,16 @@ const { title } = Astro.props;
 </RootLayout>
 
 <script>
-import { getLocalUntisCredentials } from "../api/untisAPI";
+  import { getLocalUntisCredentials } from "../api/untisAPI";
 
   if ("serviceWorker" in navigator) {
-    if(Notification.permission == "granted") {
-      navigator.serviceWorker.register("/serviceWorker.js", { scope: "/home" }).then((worker) => {
-      });
+    if (Notification.permission == "granted") {
+      navigator.serviceWorker.register("/serviceWorker.js", { scope: "/home" }).then((worker) => {});
       navigator.serviceWorker.ready.then((worker) => {
-        worker.active?.postMessage(getLocalUntisCredentials())
-      })
-    }
-    else {
-      console.log("permission denied")
+        worker.active?.postMessage(getLocalUntisCredentials());
+      });
+    } else {
+      console.log("permission denied");
     }
   }
 </script>
diff --git a/frontend/src/layouts/RootLayout.astro b/frontend/src/layouts/RootLayout.astro
index 61ff714..868e64a 100644
--- a/frontend/src/layouts/RootLayout.astro
+++ b/frontend/src/layouts/RootLayout.astro
@@ -9,211 +9,211 @@ export interface Props {
 const { title } = Astro.props;
 ---
 
-<html lang='de'>
+<html lang="de">
   <head>
-    <meta charset='UTF-8' />
+    <meta charset="UTF-8" />
     <meta
-      name='description'
-      content='Mit TheSchedule kannst du deinen Stundenplan individuell anpassen und dir Änderungen übersichtlich anzeigen lassen.'
+      name="description"
+      content="Mit TheSchedule kannst du deinen Stundenplan individuell anpassen und dir Änderungen übersichtlich anzeigen lassen."
     />
-    <meta name='apple-mobile-web-app-capable' content='yes' />
-    <link rel='apple-touch-icon' href='icons/apple-icon-180.png' />
+    <meta name="apple-mobile-web-app-capable" content="yes" />
+    <link rel="apple-touch-icon" href="icons/apple-icon-180.png" />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2048-2732.png'
-      media='(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2048-2732.png"
+      media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2732-2048.png'
-      media='(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2732-2048.png"
+      media="(prefers-color-scheme: dark) and (device-width: 1024px) and (device-height: 1366px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1668-2388.png'
-      media='(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1668-2388.png"
+      media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2388-1668.png'
-      media='(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2388-1668.png"
+      media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1194px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1536-2048.png'
-      media='(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1536-2048.png"
+      media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2048-1536.png'
-      media='(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2048-1536.png"
+      media="(prefers-color-scheme: dark) and (device-width: 768px) and (device-height: 1024px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1488-2266.png'
-      media='(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1488-2266.png"
+      media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2266-1488.png'
-      media='(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2266-1488.png"
+      media="(prefers-color-scheme: dark) and (device-width: 744px) and (device-height: 1133px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1640-2360.png'
-      media='(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1640-2360.png"
+      media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2360-1640.png'
-      media='(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2360-1640.png"
+      media="(prefers-color-scheme: dark) and (device-width: 820px) and (device-height: 1180px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1668-2224.png'
-      media='(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1668-2224.png"
+      media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2224-1668.png'
-      media='(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2224-1668.png"
+      media="(prefers-color-scheme: dark) and (device-width: 834px) and (device-height: 1112px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1620-2160.png'
-      media='(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1620-2160.png"
+      media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2160-1620.png'
-      media='(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2160-1620.png"
+      media="(prefers-color-scheme: dark) and (device-width: 810px) and (device-height: 1080px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1290-2796.png'
-      media='(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1290-2796.png"
+      media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2796-1290.png'
-      media='(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2796-1290.png"
+      media="(prefers-color-scheme: dark) and (device-width: 430px) and (device-height: 932px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1179-2556.png'
-      media='(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1179-2556.png"
+      media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2556-1179.png'
-      media='(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2556-1179.png"
+      media="(prefers-color-scheme: dark) and (device-width: 393px) and (device-height: 852px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1284-2778.png'
-      media='(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1284-2778.png"
+      media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2778-1284.png'
-      media='(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2778-1284.png"
+      media="(prefers-color-scheme: dark) and (device-width: 428px) and (device-height: 926px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1170-2532.png'
-      media='(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1170-2532.png"
+      media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2532-1170.png'
-      media='(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2532-1170.png"
+      media="(prefers-color-scheme: dark) and (device-width: 390px) and (device-height: 844px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1125-2436.png'
-      media='(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1125-2436.png"
+      media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2436-1125.png'
-      media='(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2436-1125.png"
+      media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 812px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1242-2688.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1242-2688.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2688-1242.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2688-1242.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-828-1792.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-828-1792.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1792-828.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1792-828.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 896px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1242-2208.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1242-2208.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-2208-1242.png'
-      media='(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-2208-1242.png"
+      media="(prefers-color-scheme: dark) and (device-width: 414px) and (device-height: 736px) and (-webkit-device-pixel-ratio: 3) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-750-1334.png'
-      media='(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-750-1334.png"
+      media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1334-750.png'
-      media='(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1334-750.png"
+      media="(prefers-color-scheme: dark) and (device-width: 375px) and (device-height: 667px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-640-1136.png'
-      media='(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-640-1136.png"
+      media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)"
     />
     <link
-      rel='apple-touch-startup-image'
-      href='AppImages/ios/splash-screens/apple-splash-dark-1136-640.png'
-      media='(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)'
+      rel="apple-touch-startup-image"
+      href="AppImages/ios/splash-screens/apple-splash-dark-1136-640.png"
+      media="(prefers-color-scheme: dark) and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: landscape)"
     />
-    <link rel='icon' href={favicon} />
-    <link rel='manifest' href='/manifest.webmanifest' />
-    <meta name='viewport' content='width=device-width, initial-scale=1' />
-    <meta name='theme-color' content='#1e2030' />
+    <link rel="icon" href={favicon} />
+    <link rel="manifest" href="/manifest.webmanifest" />
+    <meta name="viewport" content="width=device-width, initial-scale=1" />
+    <meta name="theme-color" content="#1e2030" />
     <title>{title}</title>
   </head>
   <body>
     <CookieBanner client:load />
     <slot />
   </body>
- <style is:global>
-  :root {
-    --background-color: #24273a;
-    --text-color: #cad3f5;
-    --text-gradient: linear-gradient(
-      90deg,
-      rgba(198, 160, 246, 1) 0%,
-      rgba(237, 135, 150, 1) 50%,
-      rgba(238, 212, 159, 1) 100%
-    );
-    --highlight-blue: #5974e2;
-    --highlight-red: #e44040;
-  }
-  ::selection {
-    background: #1a1d2f;
-    color: #b8c0e0;
-  }
+  <style is:global>
+    :root {
+      --background-color: #24273a;
+      --text-color: #cad3f5;
+      --text-gradient: linear-gradient(
+        90deg,
+        rgba(198, 160, 246, 1) 0%,
+        rgba(237, 135, 150, 1) 50%,
+        rgba(238, 212, 159, 1) 100%
+      );
+      --highlight-blue: #5974e2;
+      --highlight-red: #e44040;
+    }
+    ::selection {
+      background: #1a1d2f;
+      color: #b8c0e0;
+    }
   </style>
 </html>
diff --git a/frontend/src/pwa/cachingStrategies.ts b/frontend/src/pwa/cachingStrategies.ts
index 2fa4f76..a1a1699 100644
--- a/frontend/src/pwa/cachingStrategies.ts
+++ b/frontend/src/pwa/cachingStrategies.ts
@@ -19,8 +19,10 @@ export class Strategies {
     return (
       response ||
       fetch(event.request).then(async (response): Promise<Response> => {
-        const cache = await caches.open(cacheName);
-        cache.put(event.request, response.clone());
+        if (response.ok) {
+          const cache = await caches.open(cacheName);
+          cache.put(event.request, response.clone());
+        }
         return response;
       })
     );
@@ -40,8 +42,10 @@ export class Strategies {
   public static async StaleWhileRevalidate(event: FetchEvent, cacheName: string = "generic"): Promise<Response> {
     return caches.match(event.request).then((cacheResponse: Response | undefined) => {
       let fetchResponse = fetch(event.request).then(async (response): Promise<Response> => {
-        const cache = await caches.open(cacheName);
-        cache.put(event.request, response.clone());
+        if (response.ok) {
+          const cache = await caches.open(cacheName);
+          cache.put(event.request, response.clone());
+        }
         return response;
       });
       return cacheResponse || fetchResponse || this.ErrorMessage();
diff --git a/frontend/src/pwa/serviceWorker.ts b/frontend/src/pwa/serviceWorker.ts
index e8a738d..b3ffa93 100644
--- a/frontend/src/pwa/serviceWorker.ts
+++ b/frontend/src/pwa/serviceWorker.ts
@@ -2,12 +2,11 @@
  * @author Sxyntheon
  *
  * @description Service Worker for enabling offline experience with TheSchedule
-**/
-import { Strategies }  from "./cachingStrategies"
+ **/
+import { Strategies } from "./cachingStrategies";
 
 const cache: string = "v1";
 
-
 async function cacheFonts(event: FetchEvent): Promise<Response> {
   return Strategies.CacheFirst(event);
 }
@@ -18,7 +17,7 @@ async function cacheScripts(event: FetchEvent): Promise<Response> {
   return Strategies.CacheFirst(event);
 }
 async function cacheComponents(event: FetchEvent): Promise<Response> {
-  return Strategies.StaleWhileRevalidate(event)
+  return Strategies.StaleWhileRevalidate(event);
 }
 async function handleFetch(event: FetchEvent): Promise<Response> {
   const url = new URL(event.request.url);
@@ -26,23 +25,23 @@ async function handleFetch(event: FetchEvent): Promise<Response> {
   const backend_url = "https://api.theschedule.de";
   const untis_domain = "https://borys.webuntis.com";
   if (url.href.startsWith(untis_domain) || event.request.method != "GET") {
-    return Strategies.NetworkOnly(event)
+    return Strategies.NetworkOnly(event);
   }
   if (url.href.startsWith(backend_url)) {
-    console.log(url, " is blacklisted")
+    console.log(url, " is blacklisted");
 
     switch (url.pathname) {
       case "/get_timetable":
-        console.log("Timetable is network first")
-        return Strategies.StaleWhileRevalidate(event)
+        console.log("Timetable is network first");
+        return Strategies.StaleWhileRevalidate(event);
       case "/get_lernbueros":
-        console.log("LBs is Cache first")
-        return Strategies.StaleWhileRevalidate(event)
+        console.log("LBs is Cache first");
+        return Strategies.StaleWhileRevalidate(event);
       case "/get_free_rooms":
-        console.log("Free Rooms is Cache first")
-        return Strategies.StaleWhileRevalidate(event)
+        console.log("Free Rooms is Cache first");
+        return Strategies.StaleWhileRevalidate(event);
     }
-    return Strategies.NetworkOnly(event)
+    return Strategies.NetworkOnly(event);
   }
   if (!fileExtension) {
     return Strategies.NetworkRevalidateAndCache(event);
@@ -54,21 +53,21 @@ async function handleFetch(event: FetchEvent): Promise<Response> {
         return cacheFonts(event);
       case ".css":
         console.log(url);
-        console.count("css from cache")
+        console.count("css from cache");
         return cacheStyles(event);
       case ".js":
-        console.log(url)
-        console.count("Script from Cache")
-        return cacheScripts(event)
+        console.log(url);
+        console.count("Script from Cache");
+        return cacheScripts(event);
       case ".svg":
-        return cacheStyles(event)
+        return cacheStyles(event);
       default:
         console.log(url);
-        console.count("default caching")
+        console.count("default caching");
         return Strategies.NetworkOnly(event);
     }
   }
 }
 self.addEventListener("fetch", (event: FetchEvent) => {
   event.respondWith(handleFetch(event));
-});
\ No newline at end of file
+});
diff --git a/frontend/src/styles/Stundenplan.scss b/frontend/src/styles/Stundenplan.scss
index 57c35b6..e7daa40 100644
--- a/frontend/src/styles/Stundenplan.scss
+++ b/frontend/src/styles/Stundenplan.scss
@@ -58,7 +58,6 @@
           font-size: clamp(0rem, 100%, 2vh);
         }
         & > select option {
-          
           background-color: #24273a;
         }
       }