Skip to content

Commit 3900c63

Browse files
authored
feat: replace anyhow with proper error variants in message stores (#279)
* Move message verification errors into their own module * Move SessionError into the session module * Introduce StoreError for message store related errors * Remove redb message store as the append-only file one is superior * Clean up file store error handling * Robustness improvements for the MongoDB store * Add dedicated mongodb tests * Add test suite dedicated to file-based storage * Remove duplication in store test suites * Trim store test suites to focus on meaningful cases * Remove step to run tests in CI job which is already covered by the coverage job
1 parent 74cb1ca commit 3900c63

24 files changed

Lines changed: 540 additions & 382 deletions

.github/workflows/ci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,6 @@ jobs:
2121
run: cargo clippy -- -Dclippy::all -D warnings
2222
- name: Run clippy (all targets and features)
2323
run: cargo clippy --all-targets --all-features -- -Dclippy::all -D warnings
24-
- name: Run tests
25-
run: cargo test --verbose
2624

2725
coverage:
2826
runs-on: ubuntu-latest

Cargo.lock

Lines changed: 0 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ proc-macro2 = "1"
4141
quickcheck = "1"
4242
quickcheck_macros = "1"
4343
quote = "1"
44-
redb = "3.1"
4544
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
4645
roxmltree = "0.21"
4746
rust-embed = "8.7"

crates/hotfix/Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ categories.workspace = true
1414
[features]
1515
default = ["test-utils"]
1616
fix44 = ["hotfix-message/fix44"]
17-
redb = ["dep:redb"]
1817
mongodb = ["dep:mongodb"]
1918
test-utils = []
2019

@@ -31,7 +30,6 @@ chrono-tz = { workspace = true, features = ["serde"] }
3130
futures = { workspace = true }
3231
mongodb = { workspace = true, optional = true }
3332
rustls-pki-types = { workspace = true }
34-
redb = { workspace = true, optional = true }
3533
rustls = { workspace = true }
3634
rustls-native-certs = { workspace = true }
3735
rustls-pemfile = { workspace = true }

crates/hotfix/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727

2828
pub mod application;
2929
pub mod config;
30-
pub(crate) mod error;
3130
pub mod initiator;
3231
pub mod message;
3332
pub mod message_utils;

crates/hotfix/src/message.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ pub mod resend_request;
1414
pub mod sequence_reset;
1515
pub mod test_request;
1616
pub mod verification;
17+
pub mod verification_error;
1718

1819
pub use parser::RawFixMessage;
1920
pub use resend_request::ResendRequest;

crates/hotfix/src/message/verification.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::config::SessionConfig;
2-
use crate::error::{CompIdType, MessageVerificationError};
2+
use crate::message::verification_error::{CompIdType, MessageVerificationError};
33
use hotfix_message::Part;
44
use hotfix_message::field_types::Timestamp;
55
use hotfix_message::message::Message;
@@ -180,8 +180,9 @@ fn check_target_comp_id(
180180

181181
#[cfg(test)]
182182
mod tests {
183-
use super::{Message, MessageVerificationError, SessionConfig, verify_message};
184-
use crate::error::CompIdType;
183+
use super::{Message, SessionConfig, verify_message};
184+
use crate::message::verification_error::CompIdType;
185+
use crate::message::verification_error::MessageVerificationError;
185186
use hotfix_message::field_types::Timestamp;
186187
use hotfix_message::{Part, fix44};
187188

crates/hotfix/src/error.rs renamed to crates/hotfix/src/message/verification_error.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,9 +53,3 @@ pub enum CompIdType {
5353
Sender,
5454
Target,
5555
}
56-
57-
#[derive(Debug, Error)]
58-
pub enum SessionError {
59-
#[error("Schedule configuration is invalid: {0}")]
60-
InvalidSchedule(String),
61-
}

crates/hotfix/src/session.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
pub(crate) mod admin_request;
2+
pub mod error;
23
pub(crate) mod event;
34
mod info;
45
mod session_handle;
@@ -26,15 +27,17 @@ use tracing::{debug, enabled, error, info, warn};
2627

2728
use crate::Application;
2829
use crate::application::{InboundDecision, OutboundDecision};
29-
use crate::error::{CompIdType, MessageVerificationError};
3030
use crate::message::logout::Logout;
3131
use crate::message::reject::Reject;
3232
use crate::message::resend_request::ResendRequest;
3333
use crate::message::sequence_reset::SequenceReset;
3434
use crate::message::test_request::TestRequest;
3535
use crate::message::verification::verify_message;
36+
use crate::message::verification_error::{CompIdType, MessageVerificationError};
3637
use crate::message_utils::{is_admin, prepare_message_for_resend};
3738
use crate::session::admin_request::AdminRequest;
39+
pub use crate::session::info::{SessionInfo, Status};
40+
pub use crate::session::session_handle::SessionHandle;
3841
#[cfg(not(feature = "test-utils"))]
3942
pub(crate) use crate::session::session_ref::InternalSessionRef;
4043
#[cfg(feature = "test-utils")]
@@ -49,9 +52,6 @@ use hotfix_message::session_fields::{
4952
SessionRejectReason, TEST_REQ_ID,
5053
};
5154

52-
pub use crate::session::info::{SessionInfo, Status};
53-
pub use crate::session::session_handle::SessionHandle;
54-
5555
const SCHEDULE_CHECK_INTERVAL: u64 = 1;
5656

5757
struct Session<A, I, O, S> {
@@ -365,7 +365,8 @@ where
365365
}
366366
}
367367

368-
self.store.increment_target_seq_number().await
368+
self.store.increment_target_seq_number().await?;
369+
Ok(())
369370
}
370371

371372
async fn on_heartbeat(&mut self, message: &Message) -> Result<()> {
@@ -378,7 +379,8 @@ where
378379
self.reset_peer_timer(None);
379380
}
380381

381-
self.store.increment_target_seq_number().await
382+
self.store.increment_target_seq_number().await?;
383+
Ok(())
382384
}
383385

384386
async fn on_test_request(&mut self, message: &Message) -> Result<()> {
@@ -515,7 +517,8 @@ where
515517
return Ok(());
516518
}
517519

518-
self.store.set_target_seq_number(end - 1).await
520+
self.store.set_target_seq_number(end - 1).await?;
521+
Ok(())
519522
}
520523

521524
async fn handle_verification_error(&mut self, error: MessageVerificationError) -> Result<()> {
@@ -1129,6 +1132,7 @@ mod tests {
11291132
use super::*;
11301133
use crate::application::{InboundDecision, OutboundDecision};
11311134
use crate::message::{InboundMessage, OutboundMessage};
1135+
use crate::store::{Result as StoreResult, StoreError};
11321136
use chrono::{DateTime, Datelike, NaiveDate, NaiveTime, TimeDelta, Timelike};
11331137
use chrono_tz::Tz;
11341138
use hotfix_message::message::Message;
@@ -1168,11 +1172,11 @@ mod tests {
11681172

11691173
#[async_trait::async_trait]
11701174
impl MessageStore for TestStore {
1171-
async fn add(&mut self, _sequence_number: u64, _message: &[u8]) -> Result<()> {
1175+
async fn add(&mut self, _sequence_number: u64, _message: &[u8]) -> StoreResult<()> {
11721176
Ok(())
11731177
}
11741178

1175-
async fn get_slice(&self, _begin: usize, _end: usize) -> Result<Vec<Vec<u8>>> {
1179+
async fn get_slice(&self, _begin: usize, _end: usize) -> StoreResult<Vec<Vec<u8>>> {
11761180
Ok(vec![])
11771181
}
11781182

@@ -1184,25 +1188,25 @@ mod tests {
11841188
self.target_seq
11851189
}
11861190

1187-
async fn increment_sender_seq_number(&mut self) -> Result<()> {
1191+
async fn increment_sender_seq_number(&mut self) -> StoreResult<()> {
11881192
self.sender_seq += 1;
11891193
Ok(())
11901194
}
11911195

1192-
async fn increment_target_seq_number(&mut self) -> Result<()> {
1196+
async fn increment_target_seq_number(&mut self) -> StoreResult<()> {
11931197
self.target_seq += 1;
11941198
Ok(())
11951199
}
11961200

1197-
async fn set_target_seq_number(&mut self, seq_number: u64) -> Result<()> {
1201+
async fn set_target_seq_number(&mut self, seq_number: u64) -> StoreResult<()> {
11981202
self.target_seq = seq_number;
11991203
Ok(())
12001204
}
12011205

1202-
async fn reset(&mut self) -> Result<()> {
1206+
async fn reset(&mut self) -> StoreResult<()> {
12031207
self.reset_called.store(true, Ordering::SeqCst);
12041208
if self.fail_reset.load(Ordering::SeqCst) {
1205-
bail!("simulated reset failure")
1209+
return Err(StoreError::Reset("simulated reset failure".into()));
12061210
}
12071211
self.creation_time = Utc::now();
12081212
Ok(())

crates/hotfix/src/session/error.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use crate::store::StoreError;
2+
use thiserror::Error;
3+
4+
#[derive(Debug, Error)]
5+
pub enum SessionError {
6+
#[error("Schedule configuration is invalid: {0}")]
7+
InvalidSchedule(String),
8+
9+
#[error("store operation failed")]
10+
Store(#[from] StoreError),
11+
}
12+
13+
pub type Result<T> = std::result::Result<T, SessionError>;

0 commit comments

Comments
 (0)