aboutsummaryrefslogtreecommitdiffstats
path: root/mumd/src
diff options
context:
space:
mode:
authorEskil <eskilq@kth.se>2020-10-16 02:36:13 +0200
committerEskil <eskilq@kth.se>2020-10-16 02:36:13 +0200
commit27d8b16b40a5f5a0633c2e54640999d4e6cdd9a3 (patch)
tree769971b8921aa2c0d5c2845323a898f1603cfebe /mumd/src
parent18a3c0b3cf8254b70857e31ddd2b6213b10db156 (diff)
parentd15a4adb457b8caab4e76baff8e27ade347a275d (diff)
downloadmum-27d8b16b40a5f5a0633c2e54640999d4e6cdd9a3.tar.gz
Merge branch 'error-handling' into 'main'
Error handling Closes #13 See merge request gustav/mum!3
Diffstat (limited to 'mumd/src')
-rw-r--r--mumd/src/command.rs6
-rw-r--r--mumd/src/main.rs10
-rw-r--r--mumd/src/network.rs (renamed from mumd/src/network/mod.rs)0
-rw-r--r--mumd/src/state.rs43
4 files changed, 32 insertions, 27 deletions
diff --git a/mumd/src/command.rs b/mumd/src/command.rs
index 9adf7d8..57eaaa3 100644
--- a/mumd/src/command.rs
+++ b/mumd/src/command.rs
@@ -8,12 +8,10 @@ use tokio::sync::mpsc;
pub async fn handle(
state: Arc<Mutex<State>>,
- mut command_receiver: mpsc::UnboundedReceiver<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>,
+ mut command_receiver: mpsc::UnboundedReceiver<(Command, IpcSender<mumlib::error::Result<Option<CommandResponse>>>)>,
) {
debug!("Begin listening for commands");
- loop {
- debug!("Enter loop");
- let command = command_receiver.recv().await.unwrap();
+ while let Some(command) = command_receiver.recv().await {
debug!("Received command {:?}", command.0);
let mut state = state.lock().unwrap();
let (wait_for_connected, command_response) = state.handle_command(command.0).await;
diff --git a/mumd/src/main.rs b/mumd/src/main.rs
index 14a43c1..3a0d7ec 100644
--- a/mumd/src/main.rs
+++ b/mumd/src/main.rs
@@ -27,7 +27,7 @@ async fn main() {
// For simplicity we don't deal with re-syncing, real applications would have to.
let (crypt_state_sender, crypt_state_receiver) = mpsc::channel::<ClientCryptState>(1); // crypt state should always be consumed before sending a new one
let (packet_sender, packet_receiver) = mpsc::unbounded_channel::<ControlPacket<Serverbound>>();
- let (command_sender, command_receiver) = mpsc::unbounded_channel::<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>();
+ let (command_sender, command_receiver) = mpsc::unbounded_channel::<(Command, IpcSender<mumlib::error::Result<Option<CommandResponse>>>)>();
let (connection_info_sender, connection_info_receiver) =
watch::channel::<Option<ConnectionInfo>>(None);
@@ -61,17 +61,17 @@ async fn main() {
}
fn receive_oneshot_commands(
- command_sender: mpsc::UnboundedSender<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>,
+ command_sender: mpsc::UnboundedSender<(Command, IpcSender<mumlib::error::Result<Option<CommandResponse>>>)>,
) {
loop {
// create listener
- let (server, server_name): (IpcOneShotServer<(Command, IpcSender<Result<Option<CommandResponse>, ()>>)>, String) = IpcOneShotServer::new().unwrap();
+ let (server, server_name): (IpcOneShotServer<(Command, IpcSender<mumlib::error::Result<Option<CommandResponse>>>)>, String) = IpcOneShotServer::new().unwrap();
fs::write("/var/tmp/mumd-oneshot", &server_name).unwrap();
debug!("Listening to {}", server_name);
// receive command and response channel
- let (_, conn): (_, (Command, IpcSender<Result<Option<CommandResponse>, ()>>)) = server.accept().unwrap();
- debug!("Sending to command handler: {:#?}", conn.0);
+ let (_, conn): (_, (Command, IpcSender<mumlib::error::Result<Option<CommandResponse>>>)) = server.accept().unwrap();
+ debug!("Sending command {:?} to command handler", conn.0);
command_sender.send(conn).unwrap();
}
}
diff --git a/mumd/src/network/mod.rs b/mumd/src/network.rs
index 1a31ee2..1a31ee2 100644
--- a/mumd/src/network/mod.rs
+++ b/mumd/src/network.rs
diff --git a/mumd/src/state.rs b/mumd/src/state.rs
index 72197f6..82d671e 100644
--- a/mumd/src/state.rs
+++ b/mumd/src/state.rs
@@ -9,6 +9,7 @@ use mumlib::command::{Command, CommandResponse};
use mumlib::state::Server;
use std::net::ToSocketAddrs;
use tokio::sync::{mpsc, watch};
+use mumlib::error::Error;
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum StatePhase {
@@ -50,12 +51,16 @@ impl State {
pub async fn handle_command(
&mut self,
command: Command,
- ) -> (bool, Result<Option<CommandResponse>, ()>) {
+ ) -> (bool, mumlib::error::Result<Option<CommandResponse>>) {
match command {
Command::ChannelJoin { channel_id } => {
if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) {
- warn!("Not connected");
- return (false, Err(()));
+ return (false, Err(Error::DisconnectedError));
+ }
+ if let Some(server) = &self.server {
+ if !server.channels().contains_key(&channel_id) {
+ return (false, Err(Error::InvalidChannelIdError(channel_id)));
+ }
}
let mut msg = msgs::UserState::new();
msg.set_session(self.session_id.unwrap());
@@ -65,12 +70,9 @@ impl State {
}
Command::ChannelList => {
if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) {
- warn!("Not connected");
- return (false, Err(()));
+ return (false, Err(Error::DisconnectedError));
}
- (
- false,
- Ok(Some(CommandResponse::ChannelList {
+ (false, Ok(Some(CommandResponse::ChannelList {
channels: self.server.as_ref().unwrap().channels().clone(),
})),
)
@@ -82,8 +84,7 @@ impl State {
accept_invalid_cert,
} => {
if !matches!(*self.phase_receiver().borrow(), StatePhase::Disconnected) {
- warn!("Tried to connect to a server while already connected");
- return (false, Err(()));
+ return (false, Err(Error::AlreadyConnectedError));
}
self.server = Some(Server::new());
self.username = Some(username);
@@ -91,11 +92,14 @@ impl State {
.0
.broadcast(StatePhase::Connecting)
.unwrap();
- let socket_addr = (host.as_ref(), port)
- .to_socket_addrs()
- .expect("Failed to parse server address")
- .next()
- .expect("Failed to resolve server address");
+
+ let socket_addr = match (host.as_ref(), port).to_socket_addrs().map(|mut e| e.next()) {
+ Ok(Some(v)) => v,
+ _ => {
+ warn!("Error parsing server addr");
+ return (false, Err(Error::InvalidServerAddrError(host, port)));
+ }
+ };
self.connection_info_sender
.broadcast(Some(ConnectionInfo::new(
socket_addr,
@@ -107,18 +111,21 @@ impl State {
}
Command::Status => {
if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) {
- warn!("Not connected");
- return (false, Err(()));
+ return (false, Err(Error::DisconnectedError));
}
(
false,
Ok(Some(CommandResponse::Status {
username: self.username.clone(),
- server_state: self.server.clone().unwrap(),
+ server_state: self.server.clone().unwrap(), //guaranteed not to panic because if we are connected, server is guaranteed to be Some
})),
)
}
Command::ServerDisconnect => {
+ if !matches!(*self.phase_receiver().borrow(), StatePhase::Connected) {
+ return (false, Err(Error::DisconnectedError));
+ }
+
self.session_id = None;
self.username = None;
self.server = None;