Skip to content

Fix: connection.rs error and improve error handling #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
[package]
name = "async-chat"
version = "0.1.0"
edition = "2024"
edition = "2021"
Copy link
Collaborator

@bansikah22 bansikah22 Apr 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nafisatou you should use the 2024 and not go back to 2021

authors = ["Christian yemele <[email protected]>"]

[dependencies]
async-std = { version = "1.7", features = ["unstable"] }
tokio = { version = "1.0", features = ["sync"] }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_json = "1.0"
anyhow = "1.0.97"
anyhow = "1.0"

39 changes: 24 additions & 15 deletions src/bin/server/connection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,55 +2,64 @@
use async_chat::utils::{self};
use async_chat::{FromClient, FromServer};
use async_std::io::BufReader;
use async_std::net::TcpStream;

Check warning on line 5 in src/bin/server/connection.rs

View workflow job for this annotation

GitHub Actions / Build and test

Diff in /home/runner/work/async-chat/async-chat/src/bin/server/connection.rs
use async_std::prelude::*;

use async_std::sync::{Arc, Mutex};
use anyhow::{bail, Result};

/// Wraps a TCP connection to a client, allowing safe async writes.
pub struct Outbound(Mutex<TcpStream>);

Check warning on line 13 in src/bin/server/connection.rs

View workflow job for this annotation

GitHub Actions / Build and test

Diff in /home/runner/work/async-chat/async-chat/src/bin/server/connection.rs

use async_std::sync::Arc;
use async_std::sync::Mutex;

pub struct Outbound(Mutex<TcpStream>);

impl Outbound {
pub fn new(to_client: TcpStream) -> Outbound {
Outbound(Mutex::new(to_client))
pub fn new(to_client: TcpStream) -> Self {
Self(Mutex::new(to_client))
}
pub async fn send(&self, packet: FromServer) -> anyhow::Result<()> {

pub async fn send(&self, packet: FromServer) -> Result<()> {
let mut guard = self.0.lock().await;
utils::send_as_json(&mut *guard, &packet).await?;
guard.flush().await?;
Ok(())
}
}

pub async fn serve(socket: TcpStream, groups: Arc<GroupTable>) -> anyhow::Result<()> {
// wrapping our connection in outbound so as to have exclusive access to it in the groups and avoid interference
/// Handles a new client connection, listens for messages, and interacts with group logic.
pub async fn serve(socket: TcpStream, groups: Arc<GroupTable>) -> Result<()> {
let outbound = Arc::new(Outbound::new(socket.clone()));
let buffered = BufReader::new(socket);
// receive data from clients
let mut from_client = utils::receive_as_json(buffered);

while let Some(request_result) = from_client.next().await {
let request = request_result?;
let result = match request {

let result: Result<()> = match request {
FromClient::Join { group_name } => {
let group = groups.get_or_create(group_name);
group.join(outbound.clone());

Check warning on line 45 in src/bin/server/connection.rs

View workflow job for this annotation

GitHub Actions / Build and test

Diff in /home/runner/work/async-chat/async-chat/src/bin/server/connection.rs
Ok(())
}
FromClient::Post {
group_name,
message,
} => match groups.get(&group_name) {
FromClient::Post { group_name, message } => match groups.get(&group_name) {
Some(group) => {
group.post(message);
Ok(())
}
None => Err(format!("Group '{}' does not exist", group_name)),
None => bail!("Group '{}' does not exist", group_name),
},
};
// not a valid request

if let Err(message) = result {
let report = FromServer::Error(message);
// send error back to client
let report = FromServer::Error(message.to_string());
outbound.send(report).await?;
}
}

println!("Client disconnected.");
Ok(())
}
Loading