From 78cedf8d4021bc81013700ec33c9ca4513a20a3a Mon Sep 17 00:00:00 2001 From: Florian Guggi Date: Mon, 15 Jul 2024 12:51:43 +0200 Subject: [PATCH] Replaced boxed errors with anyhow::Error Changelog: Changed --- Cargo.lock | 76 ++++++++++++++++++++++++++++++++++ Cargo.toml | 1 + src/command/common.rs | 11 ++--- src/command/error.rs | 14 +++---- src/command/execute_program.rs | 3 +- src/command/mod.rs | 11 ++--- src/command/return_result.rs | 7 ++-- src/command/store_archive.rs | 3 +- src/command/update_time.rs | 3 +- src/communication/mod.rs | 1 - 10 files changed, 105 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4c5614f..e69af5a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,7 @@ version = 3 name = "STS1_EDU_Scheduler" version = "0.1.0" dependencies = [ + "anyhow", "crc", "file-per-thread-logger", "filevec", @@ -23,6 +24,21 @@ dependencies = [ "toml", ] +[[package]] +name = "addr2line" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "aho-corasick" version = "1.1.2" @@ -32,12 +48,36 @@ dependencies = [ "memchr", ] +[[package]] +name = "anyhow" +version = "1.0.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" +dependencies = [ + "backtrace", +] + [[package]] name = "autocfg" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -56,6 +96,12 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" +[[package]] +name = "cc" +version = "1.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "324c74f2155653c90b04f25b2a47a8a631360cb908f92a772695f430c7e31052" + [[package]] name = "cfg-if" version = "1.0.0" @@ -200,6 +246,12 @@ dependencies = [ "byteorder", ] +[[package]] +name = "gimli" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" + [[package]] name = "hashbrown" version = "0.14.3" @@ -341,6 +393,15 @@ version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +[[package]] +name = "miniz_oxide" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" +dependencies = [ + "adler", +] + [[package]] name = "mio" version = "0.8.11" @@ -391,6 +452,15 @@ dependencies = [ "libc", ] +[[package]] +name = "object" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "081b846d1d56ddfc18fdf1a922e4f6e07a11768ea1b92dec44e42b72712ccfce" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.19.0" @@ -534,6 +604,12 @@ dependencies = [ "libc", ] +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + [[package]] name = "rustix" version = "0.38.34" diff --git a/Cargo.toml b/Cargo.toml index ffbd926..3e82ed2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,6 +19,7 @@ serialport = "4.2.2" test-case = "3.3.1" tar = "0.4.40" thiserror = "1.0.62" +anyhow = { version = "1.0.86", features = ["backtrace"] } [dependencies.filevec] path = "lib/filevec" diff --git a/src/command/common.rs b/src/command/common.rs index 9636e87..0e275d8 100644 --- a/src/command/common.rs +++ b/src/command/common.rs @@ -1,5 +1,6 @@ use super::{CommandError, CommandResult, SyncExecutionContext}; use crate::communication::{CEPPacket, CommunicationHandle}; +use anyhow::anyhow; use std::time::Duration; pub fn check_length( @@ -12,9 +13,9 @@ pub fn check_length( Ok(()) } else { com.send_packet(&CEPPacket::Nack)?; - Err(CommandError::ProtocolViolation( - format!("Received command with {actual_len} bytes, expected {n}").into(), - )) + Err(CommandError::ProtocolViolation(anyhow!( + "Received command with {actual_len} bytes, expected {n}" + ))) } } @@ -48,10 +49,10 @@ pub fn terminate_student_program(exec: &mut SyncExecutionContext) -> CommandResu .take() .unwrap() .join() - .or(Err(CommandError::NonRecoverable("Supervisor thread panicked".into())))?; + .or(Err(CommandError::NonRecoverable(anyhow!("Supervisor thread panicked"))))?; return Ok(()); } } - Err(CommandError::NonRecoverable("Supervisor thread did not finish in time".into())) + Err(CommandError::NonRecoverable(anyhow!("Supervisor thread did not finish in time"))) } diff --git a/src/command/error.rs b/src/command/error.rs index 4fe8828..9928454 100644 --- a/src/command/error.rs +++ b/src/command/error.rs @@ -1,15 +1,13 @@ use crate::communication::CommunicationError; -type BoxedError = Box; - #[derive(Debug, thiserror::Error)] pub enum CommandError { - #[error("Non-recoverable: {0}")] - NonRecoverable(BoxedError), - #[error("External: {0}")] - External(BoxedError), - #[error("Protocol Violation: {0}")] - ProtocolViolation(BoxedError), + #[error("Non-recoverable: {0:?}")] + NonRecoverable(anyhow::Error), + #[error("External: {0:?}")] + External(anyhow::Error), + #[error("Protocol Violation: {0:?}")] + ProtocolViolation(anyhow::Error), } impl From for CommandError { diff --git a/src/command/execute_program.rs b/src/command/execute_program.rs index 6603d8e..24a9313 100644 --- a/src/command/execute_program.rs +++ b/src/command/execute_program.rs @@ -6,6 +6,7 @@ use crate::{ }, communication::{CEPPacket, CommunicationHandle}, }; +use anyhow::anyhow; use std::{ io::ErrorKind, path::{Path, PathBuf}, @@ -73,7 +74,7 @@ pub fn execute_program( fn create_student_process(program_id: u16, timestamp: u32) -> Result { let program_path = format!("./archives/{program_id}/main.py"); if !Path::new(&program_path).exists() { - return Err(CommandError::ProtocolViolation("Could not find matching program".into())); + return Err(CommandError::ProtocolViolation(anyhow!("Could not find matching program"))); } // TODO run the program from a student user (setuid) diff --git a/src/command/mod.rs b/src/command/mod.rs index e852fff..7db021c 100644 --- a/src/command/mod.rs +++ b/src/command/mod.rs @@ -9,6 +9,7 @@ mod store_archive; mod update_time; use crate::communication::{CEPPacket, CommunicationHandle}; +use anyhow::anyhow; pub use common::*; pub use error::CommandError; use execute_program::execute_program; @@ -50,13 +51,13 @@ pub fn process_command( ) -> CommandResult { let packet = com.receive_packet()?; let CEPPacket::Data(data) = packet else { - return Err(CommandError::NonRecoverable( - format!("Received {packet:?} as command start, expected Data").into(), - )); + return Err(CommandError::NonRecoverable(anyhow!( + "Received {packet:?} as command start, expected Data" + ))); }; if data.is_empty() { - return Err(CommandError::ProtocolViolation("No data sent with data packet".into())); + return Err(CommandError::ProtocolViolation(anyhow!("Received empty data packet"))); } match data.first().unwrap() { @@ -67,7 +68,7 @@ pub fn process_command( 0x05 => return_result(&data, com, exec)?, 0x06 => update_time(&data, com, exec)?, b => { - return Err(CommandError::ProtocolViolation(format!("Unknown command {b:#x}").into())); + return Err(CommandError::ProtocolViolation(anyhow!("Unknown command {b:#x}"))); } }; diff --git a/src/command/return_result.rs b/src/command/return_result.rs index f42b642..449d7e7 100644 --- a/src/command/return_result.rs +++ b/src/command/return_result.rs @@ -3,6 +3,7 @@ use crate::{ command::{check_length, CommandError, Event, ResultId, COMMAND_TIMEOUT}, communication::{CEPPacket, CommunicationHandle}, }; +use anyhow::anyhow; /// Handles a complete return result command. The result tar file is only deleted if a final Ack is /// received. @@ -19,9 +20,9 @@ pub fn return_result( if !std::path::Path::new(&result_path).exists() { com.send_packet(&CEPPacket::Nack)?; - return Err(CommandError::ProtocolViolation( - format!("Result {program_id}:{timestamp} does not exist").into(), - )); + return Err(CommandError::ProtocolViolation(anyhow!( + "Result {program_id}:{timestamp} does not exist" + ))); } let bytes = std::fs::read(result_path)?; diff --git a/src/command/store_archive.rs b/src/command/store_archive.rs index 00a1747..e80f990 100644 --- a/src/command/store_archive.rs +++ b/src/command/store_archive.rs @@ -3,6 +3,7 @@ use crate::{ command::check_length, communication::{CEPPacket, CommunicationHandle}, }; +use anyhow::anyhow; use std::{io::Write, process::Command}; /// This function implements the Store Archive command, including the reception of the archive itself @@ -49,7 +50,7 @@ fn unpack_archive(folder: &str, bytes: &[u8]) -> CommandResult { match exit_status { Ok(status) => { if !status.success() { - return Err(CommandError::NonRecoverable("unzip failed".into())); + return Err(CommandError::NonRecoverable(anyhow!("unzip failed"))); } } Err(err) => { diff --git a/src/command/update_time.rs b/src/command/update_time.rs index 71cb039..e305fe6 100644 --- a/src/command/update_time.rs +++ b/src/command/update_time.rs @@ -1,5 +1,6 @@ use super::{check_length, CommandError, CommandResult, SyncExecutionContext}; use crate::communication::{CEPPacket, CommunicationHandle}; +use anyhow::anyhow; use std::process::Command; /// Handles the update time command @@ -20,7 +21,7 @@ pub fn update_time( fn set_system_time(s_since_epoch: i32) -> CommandResult { let exit_status = Command::new("date").arg("-s").arg(format!("@{s_since_epoch}")).status()?; if !exit_status.success() { - return Err(CommandError::NonRecoverable("date utility failed".into())); + return Err(CommandError::NonRecoverable(anyhow!("date utility failed"))); } Ok(()) diff --git a/src/communication/mod.rs b/src/communication/mod.rs index abe12b5..b330c29 100644 --- a/src/communication/mod.rs +++ b/src/communication/mod.rs @@ -173,7 +173,6 @@ impl From for CommunicationError { } } - #[allow(clippy::needless_pass_by_value)] #[cfg(test)] mod tests {