diff --git a/emgauwa-controller/src/main.rs b/emgauwa-controller/src/main.rs
index 546822b..6ff6f65 100644
--- a/emgauwa-controller/src/main.rs
+++ b/emgauwa-controller/src/main.rs
@@ -1,6 +1,6 @@
 use emgauwa_lib::constants::WEBSOCKET_RETRY_TIMEOUT;
 use emgauwa_lib::db::{DbController, DbJunctionRelaySchedule, DbRelay, DbSchedule};
-use emgauwa_lib::errors::DatabaseError;
+use emgauwa_lib::errors::{DatabaseError, EmgauwaError};
 use emgauwa_lib::models::{Controller, FromDbModel};
 use emgauwa_lib::types::{ControllerUid, ControllerWsAction};
 use emgauwa_lib::{db, utils};
@@ -23,7 +23,7 @@ mod settings;
 async fn create_this_controller(
 	conn: &mut PoolConnection<Sqlite>,
 	settings: &Settings,
-) -> DbController {
+) -> Result<DbController, EmgauwaError> {
 	DbController::create(
 		conn,
 		&ControllerUid::default(),
@@ -31,18 +31,20 @@ async fn create_this_controller(
 		settings.relays.len() as i64,
 	)
 	.await
-	.expect("Failed to create controller")
+	.map_err(EmgauwaError::from)
 }
 
 async fn create_this_relay(
 	conn: &mut PoolConnection<Sqlite>,
 	this_controller: &DbController,
 	settings_relay: &settings::Relay,
-) -> Result<DbRelay, DatabaseError> {
+) -> Result<DbRelay, EmgauwaError> {
 	let relay = DbRelay::create(
 		conn,
 		&settings_relay.name,
-		settings_relay.number.expect("Relay number is missing"),
+		settings_relay.number.ok_or(EmgauwaError::Internal(
+			"Relay number is missing".to_string(),
+		))?,
 		this_controller,
 	)
 	.await?;
@@ -55,7 +57,7 @@ async fn create_this_relay(
 	Ok(relay)
 }
 
-async fn run_websocket(this: Controller, url: &str) {
+async fn run_websocket(this: Controller, url: &str) -> Result<(), EmgauwaError> {
 	match connect_async(url).await {
 		Ok(connection) => {
 			let (ws_stream, _) = connection;
@@ -64,11 +66,10 @@ async fn run_websocket(this: Controller, url: &str) {
 
 			let ws_action = ControllerWsAction::Register(this.clone());
 
-			let ws_action_json =
-				serde_json::to_string(&ws_action).expect("Failed to serialize action");
+			let ws_action_json = serde_json::to_string(&ws_action)?;
 			if let Err(err) = write.send(Message::text(ws_action_json)).await {
 				log::error!("Failed to register at websocket: {}", err);
-				return;
+				return Ok(());
 			}
 
 			let read_handler = read.for_each(handle_message);
@@ -81,23 +82,23 @@ async fn run_websocket(this: Controller, url: &str) {
 			log::warn!("Failed to connect to websocket: {}", err,);
 		}
 	}
+	Ok(())
 }
 
 #[tokio::main]
-async fn main() {
-	let settings = settings::init();
-	init_logging(&settings.logging.level);
+async fn main() -> Result<(), std::io::Error> {
+	let settings = settings::init()?;
+	init_logging(&settings.logging.level)?;
 
-	let pool = db::init(&settings.database).await;
-
-	let mut conn = pool
-		.acquire()
+	let pool = db::init(&settings.database)
 		.await
-		.expect("Failed to get database connection");
+		.map_err(EmgauwaError::from)?;
+
+	let mut conn = pool.acquire().await.map_err(EmgauwaError::from)?;
 
 	let db_controller = match DbController::get_all(&mut conn)
 		.await
-		.expect("Failed to get controller from database")
+		.map_err(EmgauwaError::from)?
 		.pop()
 	{
 		None => futures::executor::block_on(create_this_controller(&mut conn, &settings)),
@@ -108,25 +109,26 @@ async fn main() {
 		if DbRelay::get_by_controller_and_num(
 			&mut conn,
 			&db_controller,
-			relay.number.expect("Relay number is missing"),
+			relay.number.ok_or(EmgauwaError::Internal(
+				"Relay number is missing".to_string(),
+			))?,
 		)
 		.await
-		.expect("Failed to get relay from database")
+		.map_err(EmgauwaError::from)?
 		.is_none()
 		{
 			create_this_relay(&mut conn, &db_controller, relay)
 				.await
-				.expect("Failed to create schedule.");
+				.map_err(EmgauwaError::from)?;
 		}
 	}
 
 	let db_controller = db_controller
 		.update(&mut conn, &db_controller.name, settings.relays.len() as i64)
 		.await
-		.expect("Failed to update controller");
+		.map_err(EmgauwaError::from)?;
 
-	let this = Controller::from_db_model(&mut conn, db_controller)
-		.expect("Failed to convert database models");
+	let this = Controller::from_db_model(&mut conn, db_controller).map_err(EmgauwaError::from)?;
 
 	let url = format!(
 		"ws://{}:{}/api/v1/ws/controllers",
@@ -136,7 +138,10 @@ async fn main() {
 	tokio::spawn(run_relay_loop(settings));
 
 	loop {
-		run_websocket(this.clone(), &url).await;
+		let run_result = run_websocket(this.clone(), &url).await;
+		if let Err(err) = run_result {
+			log::error!("Error running websocket: {}", err);
+		}
 
 		log::info!(
 			"Retrying to connect in {} seconds...",
diff --git a/emgauwa-controller/src/settings.rs b/emgauwa-controller/src/settings.rs
index ca59096..d9b86e4 100644
--- a/emgauwa-controller/src/settings.rs
+++ b/emgauwa-controller/src/settings.rs
@@ -1,3 +1,4 @@
+use emgauwa_lib::errors::EmgauwaError;
 use emgauwa_lib::{constants, utils};
 use serde_derive::Deserialize;
 
@@ -83,8 +84,8 @@ impl Default for Logging {
 	}
 }
 
-pub fn init() -> Settings {
-	let mut settings: Settings = utils::load_settings("controller", "CONTROLLER");
+pub fn init() -> Result<Settings, EmgauwaError> {
+	let mut settings: Settings = utils::load_settings("controller", "CONTROLLER")?;
 
 	for (num, relay) in settings.relays.iter_mut().enumerate() {
 		if relay.number.is_none() {
@@ -92,5 +93,5 @@ pub fn init() -> Settings {
 		}
 	}
 
-	settings
+	Ok(settings)
 }
diff --git a/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs b/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs
index c4a6425..4a4e020 100644
--- a/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs
+++ b/emgauwa-core/src/handlers/v1/ws/controllers/mod.rs
@@ -116,14 +116,17 @@ impl StreamHandler<Result<Message, ProtocolError>> for ControllerWs {
 					let action_res = self.handle_action(&mut pool_conn, ctx, action);
 					if let Err(e) = action_res {
 						log::error!("Error handling action: {:?}", e);
-						ctx.text(serde_json::to_string(&e).expect("Failed to serialize error"));
+						ctx.text(
+							serde_json::to_string(&e)
+								.unwrap_or(format!("Error in handling action: {:?}", e)),
+						);
 					}
 				}
 				Err(e) => {
 					log::error!("Error deserializing action: {:?}", e);
 					ctx.text(
 						serde_json::to_string(&EmgauwaError::Serialization(e))
-							.expect("Failed to serialize error"),
+							.unwrap_or(String::from("Error in deserializing action")),
 					);
 				}
 			},
diff --git a/emgauwa-core/src/main.rs b/emgauwa-core/src/main.rs
index 8e83d16..45c1214 100644
--- a/emgauwa-core/src/main.rs
+++ b/emgauwa-core/src/main.rs
@@ -5,6 +5,7 @@ use actix_cors::Cors;
 use actix_web::middleware::TrailingSlash;
 use actix_web::{middleware, web, App, HttpServer};
 use emgauwa_lib::db::DbController;
+use emgauwa_lib::errors::EmgauwaError;
 use emgauwa_lib::utils::init_logging;
 
 use crate::app_state::AppServer;
@@ -16,27 +17,21 @@ mod settings;
 mod utils;
 
 #[actix_web::main]
-async fn main() -> std::io::Result<()> {
-	let settings = settings::init();
-	init_logging(&settings.logging.level);
+async fn main() -> Result<(), std::io::Error> {
+	let settings = settings::init()?;
+	init_logging(&settings.logging.level)?;
 
-	let listener = TcpListener::bind(format!("{}:{}", settings.host, settings.port))
-		.expect("Error creating listener");
+	let listener = TcpListener::bind(format!("{}:{}", settings.host, settings.port))?;
 
-	drop_privileges(&settings).expect("Error dropping privileges");
+	drop_privileges(&settings)?;
 
-	let pool = emgauwa_lib::db::init(&settings.database).await;
+	let pool = emgauwa_lib::db::init(&settings.database).await?;
 
-	// This block is to ensure that the connection is dropped after use.
-	{
-		let mut conn = pool
-			.acquire()
-			.await
-			.expect("Failed to get database connection");
-		DbController::all_inactive(&mut conn)
-			.await
-			.expect("Error setting all controllers inactive");
-	}
+	let mut conn = pool.acquire().await.map_err(EmgauwaError::from)?;
+	DbController::all_inactive(&mut conn)
+		.await
+		.map_err(EmgauwaError::from)?;
+	conn.close().await.map_err(EmgauwaError::from)?;
 
 	let app_server = AppServer::new(pool.clone()).start();
 
diff --git a/emgauwa-core/src/settings.rs b/emgauwa-core/src/settings.rs
index 5c4e353..115efa6 100644
--- a/emgauwa-core/src/settings.rs
+++ b/emgauwa-core/src/settings.rs
@@ -1,3 +1,4 @@
+use emgauwa_lib::errors::EmgauwaError;
 use emgauwa_lib::{constants, utils};
 use serde_derive::Deserialize;
 
@@ -51,6 +52,6 @@ impl Default for Logging {
 	}
 }
 
-pub fn init() -> Settings {
+pub fn init() -> Result<Settings, EmgauwaError> {
 	utils::load_settings("core", "CORE")
 }
diff --git a/emgauwa-lib/src/db/mod.rs b/emgauwa-lib/src/db/mod.rs
index fd42606..0b0650d 100644
--- a/emgauwa-lib/src/db/mod.rs
+++ b/emgauwa-lib/src/db/mod.rs
@@ -19,38 +19,31 @@ pub use relays::DbRelay;
 pub use schedules::{DbPeriods, DbSchedule};
 pub use tag::DbTag;
 
+use crate::errors::{DatabaseError, EmgauwaError};
+
 static MIGRATOR: Migrator = sqlx::migrate!("../migrations"); // defaults to "./migrations"
 
-pub async fn run_migrations(pool: &Pool<Sqlite>) {
+pub async fn run_migrations(pool: &Pool<Sqlite>) -> Result<(), EmgauwaError> {
 	log::info!("Running migrations");
-	MIGRATOR.run(pool).await.expect("Failed to run migrations.");
+	MIGRATOR.run(pool).await.map_err(DatabaseError::from)?;
+	Ok(())
 }
 
-pub async fn init(db: &str) -> Pool<Sqlite> {
-	let options = SqliteConnectOptions::from_str(db)
-		.expect("Error parsing database path")
-		.create_if_missing(true);
+pub async fn init(db: &str) -> Result<Pool<Sqlite>, EmgauwaError> {
+	let options = SqliteConnectOptions::from_str(db)?.create_if_missing(true);
 
 	let pool: Pool<Sqlite> = SqlitePoolOptions::new()
 		.acquire_timeout(std::time::Duration::from_secs(1))
 		.max_connections(5)
 		.connect_with(options)
-		.await
-		.expect("Error connecting to database");
+		.await?;
 
-	run_migrations(&pool).await;
+	run_migrations(&pool).await?;
 
-	let mut pool_conn = pool
-		.acquire()
-		.await
-		.expect("Failed to acquire pool connection");
+	let mut pool_conn = pool.acquire().await?;
 
-	DbSchedule::get_on(&mut pool_conn)
-		.await
-		.expect("Failed to init 'on' schedule");
-	DbSchedule::get_off(&mut pool_conn)
-		.await
-		.expect("Failed to init 'off' schedule");
+	DbSchedule::get_on(&mut pool_conn).await?;
+	DbSchedule::get_off(&mut pool_conn).await?;
 
-	pool
+	Ok(pool)
 }
diff --git a/emgauwa-lib/src/errors/database_error.rs b/emgauwa-lib/src/errors/database_error.rs
index c221f11..3f8c482 100644
--- a/emgauwa-lib/src/errors/database_error.rs
+++ b/emgauwa-lib/src/errors/database_error.rs
@@ -2,6 +2,7 @@ use actix_web::http::StatusCode;
 use actix_web::HttpResponse;
 use serde::ser::SerializeStruct;
 use serde::{Serialize, Serializer};
+use sqlx::migrate::MigrateError;
 use sqlx::Error;
 
 #[derive(Debug)]
@@ -13,7 +14,8 @@ pub enum DatabaseError {
 	Protected,
 	UpdateError,
 	UpdateGetError,
-	Unknown(String),
+	MigrationError(MigrateError),
+	Unknown(Error),
 }
 
 impl DatabaseError {
@@ -53,6 +55,7 @@ impl From<&DatabaseError> for String {
 			DatabaseError::UpdateGetError => {
 				"error on retrieving updated model from database (your entry was saved)"
 			}
+			DatabaseError::MigrationError(_) => "error on running migrations",
 			DatabaseError::Unknown(_) => "unknown error",
 		})
 	}
@@ -68,7 +71,13 @@ impl From<Error> for DatabaseError {
 	fn from(value: Error) -> Self {
 		match value {
 			Error::RowNotFound => DatabaseError::NotFound,
-			_ => DatabaseError::Unknown(value.to_string()),
+			_ => DatabaseError::Unknown(value),
 		}
 	}
 }
+
+impl From<MigrateError> for DatabaseError {
+	fn from(value: MigrateError) -> Self {
+		Self::MigrationError(value)
+	}
+}
diff --git a/emgauwa-lib/src/errors/emgauwa_error.rs b/emgauwa-lib/src/errors/emgauwa_error.rs
index ee33ed8..b947c16 100644
--- a/emgauwa-lib/src/errors/emgauwa_error.rs
+++ b/emgauwa-lib/src/errors/emgauwa_error.rs
@@ -1,8 +1,11 @@
+use std::error::Error;
 use std::fmt::{Debug, Display, Formatter};
+use std::io::ErrorKind;
 
 use actix::MailboxError;
 use actix_web::http::StatusCode;
 use actix_web::HttpResponse;
+use config::ConfigError;
 use serde::ser::SerializeStruct;
 use serde::{Serialize, Serializer};
 
@@ -15,6 +18,7 @@ pub enum EmgauwaError {
 	Uid(uuid::Error),
 	Serialization(serde_json::Error),
 	Database(DatabaseError),
+	Other(String),
 	Internal(String),
 	Connection(ControllerUid),
 }
@@ -28,6 +32,7 @@ impl EmgauwaError {
 			EmgauwaError::Uid(_) => StatusCode::BAD_REQUEST,
 			EmgauwaError::Internal(_) => StatusCode::INTERNAL_SERVER_ERROR,
 			EmgauwaError::Connection(_) => StatusCode::GATEWAY_TIMEOUT,
+			EmgauwaError::Other(_) => StatusCode::INTERNAL_SERVER_ERROR,
 		}
 	}
 }
@@ -39,8 +44,9 @@ impl From<&EmgauwaError> for String {
 			EmgauwaError::Serialization(_) => String::from("error during (de-)serialization"),
 			EmgauwaError::Database(err) => String::from(err),
 			EmgauwaError::Uid(_) => String::from("the uid is in a bad format"),
-			EmgauwaError::Internal(_) => String::from("general error"),
+			EmgauwaError::Internal(_) => String::from("internal error"),
 			EmgauwaError::Connection(_) => String::from("the target controller is not connected"),
+			EmgauwaError::Other(err) => format!("other error: {}", err),
 		}
 	}
 }
@@ -81,12 +87,26 @@ impl From<MailboxError> for EmgauwaError {
 	}
 }
 
+impl From<ConfigError> for EmgauwaError {
+	fn from(value: ConfigError) -> Self {
+		Self::Other(value.to_string())
+	}
+}
+
 impl From<&EmgauwaError> for HttpResponse {
 	fn from(err: &EmgauwaError) -> Self {
 		HttpResponse::build(err.get_code()).json(err)
 	}
 }
 
+impl Error for EmgauwaError {}
+
+impl From<EmgauwaError> for std::io::Error {
+	fn from(value: EmgauwaError) -> Self {
+		std::io::Error::new(ErrorKind::Other, value)
+	}
+}
+
 impl Serialize for EmgauwaError {
 	fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
 	where
diff --git a/emgauwa-lib/src/types/controller_uid.rs b/emgauwa-lib/src/types/controller_uid.rs
index 0d45973..bbaded8 100644
--- a/emgauwa-lib/src/types/controller_uid.rs
+++ b/emgauwa-lib/src/types/controller_uid.rs
@@ -62,15 +62,20 @@ impl Type<Sqlite> for ControllerUid {
 impl<'q> Encode<'q, Sqlite> for ControllerUid {
 	//noinspection DuplicatedCode
 	fn encode_by_ref(&self, buf: &mut <Sqlite as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
-		let uuid_val = self.0.as_bytes().to_vec();
-		<&Vec<u8> as Encode<Sqlite>>::encode(&uuid_val, buf)
+		<Vec<u8> as Encode<Sqlite>>::encode(Vec::from(self), buf)
 	}
 }
 
 impl<'r> Decode<'r, Sqlite> for ControllerUid {
 	//noinspection DuplicatedCode
 	fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
-		Ok(Self::from(<&[u8] as Decode<Sqlite>>::decode(value)?))
+		Self::try_from(<&[u8] as Decode<Sqlite>>::decode(value)?).map_err(Into::into)
+	}
+}
+
+impl From<&ControllerUid> for Vec<u8> {
+	fn from(uid: &ControllerUid) -> Vec<u8> {
+		uid.0.as_bytes().to_vec()
 	}
 }
 
@@ -83,14 +88,16 @@ impl TryFrom<&str> for ControllerUid {
 	}
 }
 
-impl From<&[u8]> for ControllerUid {
-	fn from(value: &[u8]) -> Self {
-		Self(Uuid::from_slice(value).expect("Failed to parse controller uid from database"))
+impl TryFrom<&[u8]> for ControllerUid {
+	type Error = uuid::Error;
+
+	fn try_from(value: &[u8]) -> Result<ControllerUid, uuid::Error> {
+		Ok(Self(Uuid::from_slice(value)?))
 	}
 }
 
 impl From<Vec<u8>> for ControllerUid {
 	fn from(value: Vec<u8>) -> Self {
-		Self::from(value.as_slice())
+		Self::try_from(value.as_slice()).expect("Failed to parse controller uid from database")
 	}
 }
diff --git a/emgauwa-lib/src/types/schedule_uid.rs b/emgauwa-lib/src/types/schedule_uid.rs
index ebd696d..2e903a9 100644
--- a/emgauwa-lib/src/types/schedule_uid.rs
+++ b/emgauwa-lib/src/types/schedule_uid.rs
@@ -55,14 +55,14 @@ impl Type<Sqlite> for ScheduleUid {
 impl<'q> Encode<'q, Sqlite> for ScheduleUid {
 	//noinspection DuplicatedCode
 	fn encode_by_ref(&self, buf: &mut <Sqlite as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
-		<&Vec<u8> as Encode<Sqlite>>::encode(&Vec::from(self), buf)
+		<Vec<u8> as Encode<Sqlite>>::encode(Vec::from(self), buf)
 	}
 }
 
 impl<'r> Decode<'r, Sqlite> for ScheduleUid {
 	//noinspection DuplicatedCode
 	fn decode(value: SqliteValueRef<'r>) -> Result<Self, BoxDynError> {
-		Ok(Self::from(<&[u8] as Decode<Sqlite>>::decode(value)?))
+		Self::try_from(<&[u8] as Decode<Sqlite>>::decode(value)?).map_err(Into::into)
 	}
 }
 
@@ -140,20 +140,21 @@ impl From<&ScheduleUid> for Vec<u8> {
 	}
 }
 
-impl From<&[u8]> for ScheduleUid {
-	fn from(value: &[u8]) -> Self {
-		match value {
+impl TryFrom<&[u8]> for ScheduleUid {
+	type Error = uuid::Error;
+
+	fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
+		let result = match value {
 			[Self::OFF_U8] => Self::Off,
 			[Self::ON_U8] => Self::On,
-			value_bytes => Self::Any(
-				Uuid::from_slice(value_bytes).expect("Failed to parse schedule uid from database"),
-			),
-		}
+			value_bytes => Self::Any(Uuid::from_slice(value_bytes)?),
+		};
+		Ok(result)
 	}
 }
 
 impl From<Vec<u8>> for ScheduleUid {
 	fn from(value: Vec<u8>) -> Self {
-		Self::from(value.as_slice())
+		Self::try_from(value.as_slice()).expect("Failed to parse schedule uid from database")
 	}
 }
diff --git a/emgauwa-lib/src/utils.rs b/emgauwa-lib/src/utils.rs
index 27c253d..9f442b9 100644
--- a/emgauwa-lib/src/utils.rs
+++ b/emgauwa-lib/src/utils.rs
@@ -4,9 +4,10 @@ use chrono::Datelike;
 use log::LevelFilter;
 use simple_logger::SimpleLogger;
 
+use crate::errors::EmgauwaError;
 use crate::types::Weekday;
 
-pub fn load_settings<T>(config_name: &str, env_prefix: &str) -> T
+pub fn load_settings<T>(config_name: &str, env_prefix: &str) -> Result<T, EmgauwaError>
 where
 	for<'de> T: serde::Deserialize<'de>,
 {
@@ -19,20 +20,24 @@ where
 				.prefix_separator("__")
 				.separator("__"),
 		)
-		.build()
-		.expect("Error building settings")
+		.build()?
 		.try_deserialize::<T>()
-		.expect("Error reading settings")
+		.map_err(EmgauwaError::from)
 }
 
-pub fn init_logging(level: &str) {
-	let log_level: LevelFilter = LevelFilter::from_str(level).expect("Error parsing log level.");
+pub fn init_logging(level: &str) -> Result<(), EmgauwaError> {
+	let log_level: LevelFilter = LevelFilter::from_str(level)
+		.map_err(|_| EmgauwaError::Other(format!("Invalid log level: {}", level.to_string())))?;
 	log::trace!("Log level set to {:?}", log_level);
 
 	SimpleLogger::new()
 		.with_level(log_level)
 		.init()
-		.expect("Error initializing logger.");
+		.map_err(|err| {
+			EmgauwaError::Other(format!("Failed to initialize logger: {}", err.to_string()))
+		})?;
+
+	Ok(())
 }
 
 pub fn get_weekday() -> Weekday {