mirror of
https://github.com/facebookincubator/mvfst.git
synced 2025-11-24 04:01:07 +03:00
Convert IntervalSet from throwing exceptions to using CHECKs with Expected error handling
Summary: This commit converts IntervalSet to use CHECKs instead of throwing exceptions and provides safe tryInsert methods that return quic::Expected for error handling. **Core Problem Solved:** IntervalSet was throwing `std::invalid_argument` exceptions in two scenarios: 1. When constructing an Interval with `start > end` 2. When interval bounds exceed the maximum allowed value This change eliminates exceptions in favor of CHECKs (for internal validation) and Expected-based error handling (for caller validation). **Implementation Details:** **1. IntervalSet Core Changes:** - Replaced `throw std::invalid_argument` with `CHECK_LE` in Interval constructor - Replaced `throw std::invalid_argument` with `CHECK_LE` in `insert(start, end)` - Added `IntervalSetError` enum for error classification - Added `folly::Expected` include **2. Safe API Layer:** - Added `tryInsert(interval)` method returning `Expected<Unit, IntervalSetError>` - Added `tryInsert(start, end)` method with pre-validation - Added `tryInsert(point)` method - Added static `Interval::tryCreate()` method for safe interval construction **3. Updated Code:** - **QuicWriteCodec.cpp**: Updated `fillFrameWithPacketReceiveTimestamps` to use `tryInsert` - Returns `QuicError` if interval validation fails - Maintains existing error handling patterns - **QuicTransportFunctions.cpp**: Updated `implicitAckCryptoStream` to use `tryInsert` - Logs errors and continues processing other packets - Robust error handling for crypto stream implicit acks Reviewed By: kvtsoy Differential Revision: D76792362 fbshipit-source-id: 5bd7c22e69a91d60cc41c603a1f2380893f4c8a0
This commit is contained in:
committed by
Facebook GitHub Bot
parent
8f8be8d5d0
commit
d3e8fe246a
@@ -158,9 +158,10 @@ TEST(IntervalSet, insertWithMergeAtEdge) {
|
||||
|
||||
TEST(IntervalSet, insertBoundTooLarge) {
|
||||
IntervalSet<uint32_t, 10> set;
|
||||
EXPECT_THROW(
|
||||
set.insert(0, std::numeric_limits<uint32_t>::max() - 9),
|
||||
std::invalid_argument);
|
||||
// This should CHECK-fail since end - start > 10
|
||||
EXPECT_DEATH(
|
||||
set.insert(0, std::numeric_limits<uint32_t>::max() - 9), "Check failed");
|
||||
// This should work fine since end - start == 10
|
||||
set.insert(0, std::numeric_limits<uint32_t>::max() - 10);
|
||||
}
|
||||
|
||||
@@ -402,3 +403,77 @@ TEST(IntervalSet, equalityComparatorNotEqualDiffIntervals2) {
|
||||
EXPECT_FALSE(set1 == set2);
|
||||
EXPECT_TRUE(set1 != set2);
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryInsertValidInterval) {
|
||||
IntervalSet<int> set;
|
||||
auto result = set.tryInsert(1, 5);
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(1, set.size());
|
||||
EXPECT_TRUE(set.contains(1, 5));
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryInsertValidPoint) {
|
||||
IntervalSet<int> set;
|
||||
auto result = set.tryInsert(10);
|
||||
EXPECT_TRUE(result.has_value());
|
||||
EXPECT_EQ(1, set.size());
|
||||
EXPECT_TRUE(set.contains(10, 10));
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryInsertInvalidInterval) {
|
||||
IntervalSet<int> set;
|
||||
// start > end should return error
|
||||
auto result = set.tryInsert(10, 5);
|
||||
EXPECT_TRUE(result.hasError());
|
||||
EXPECT_EQ(IntervalSetError::InvalidInterval, result.error());
|
||||
EXPECT_EQ(0, set.size());
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryInsertBoundTooLarge) {
|
||||
IntervalSet<uint32_t, 10> set;
|
||||
// This should return error instead of CHECK-failing
|
||||
auto result = set.tryInsert(0, std::numeric_limits<uint32_t>::max() - 9);
|
||||
EXPECT_TRUE(result.hasError());
|
||||
EXPECT_EQ(IntervalSetError::IntervalBoundTooLarge, result.error());
|
||||
EXPECT_EQ(0, set.size());
|
||||
|
||||
// This should succeed
|
||||
auto result2 = set.tryInsert(0, std::numeric_limits<uint32_t>::max() - 10);
|
||||
EXPECT_TRUE(result2.has_value());
|
||||
EXPECT_EQ(1, set.size());
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryInsertWithMerging) {
|
||||
IntervalSet<int> set;
|
||||
auto result1 = set.tryInsert(1, 3);
|
||||
EXPECT_TRUE(result1.has_value());
|
||||
|
||||
auto result2 = set.tryInsert(5, 7);
|
||||
EXPECT_TRUE(result2.has_value());
|
||||
|
||||
// Insert overlapping interval
|
||||
auto result3 = set.tryInsert(2, 6);
|
||||
EXPECT_TRUE(result3.has_value());
|
||||
|
||||
EXPECT_EQ(1, set.size());
|
||||
EXPECT_TRUE(set.contains(1, 7));
|
||||
}
|
||||
|
||||
TEST(IntervalSet, tryCreateInterval) {
|
||||
// Test the static tryCreate method
|
||||
auto result1 = Interval<int>::tryCreate(1, 5);
|
||||
EXPECT_TRUE(result1.has_value());
|
||||
EXPECT_EQ(1, result1->start);
|
||||
EXPECT_EQ(5, result1->end);
|
||||
|
||||
// Test invalid interval
|
||||
auto result2 = Interval<int>::tryCreate(10, 5);
|
||||
EXPECT_TRUE(result2.hasError());
|
||||
EXPECT_EQ(IntervalSetError::InvalidInterval, result2.error());
|
||||
|
||||
// Test bound too large
|
||||
auto result3 = Interval<uint32_t, 10>::tryCreate(
|
||||
0, std::numeric_limits<uint32_t>::max() - 9);
|
||||
EXPECT_TRUE(result3.hasError());
|
||||
EXPECT_EQ(IntervalSetError::IntervalBoundTooLarge, result3.error());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user