Skip to content

Commit b550506

Browse files
committed
Reapply "Fix risky unwrap(), expect(), and casting (sonic-net#1113)" (sonic-net#1118)
This reverts commit 7682785.
1 parent 7f1b50f commit b550506

15 files changed

Lines changed: 99 additions & 41 deletions

common/c-api/consumerstatetable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ SWSSResult SWSSConsumerStateTable_pops(SWSSConsumerStateTable tbl,
3838
});
3939
}
4040

41-
SWSSResult SWSSConsumerStateTable_getFd(SWSSConsumerStateTable tbl, uint32_t *outFd) {
42-
SWSSTry(*outFd = numeric_cast<uint32_t>(((ConsumerStateTable *)tbl)->getFd()));
41+
SWSSResult SWSSConsumerStateTable_getFd(SWSSConsumerStateTable tbl, int32_t *outFd) {
42+
SWSSTry(*outFd = ((ConsumerStateTable *)tbl)->getFd());
4343
}
4444

4545
SWSSResult SWSSConsumerStateTable_readData(SWSSConsumerStateTable tbl, uint32_t timeout_ms,

common/c-api/consumerstatetable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ SWSSResult SWSSConsumerStateTable_pops(SWSSConsumerStateTable tbl, SWSSKeyOpFiel
2626
// Callers must NOT read/write on the fd, it may only be used for epoll or similar.
2727
// After the fd becomes readable, SWSSConsumerStateTable_readData must be used to
2828
// reset the fd and read data into internal data structures.
29-
SWSSResult SWSSConsumerStateTable_getFd(SWSSConsumerStateTable tbl, uint32_t *outFd);
29+
SWSSResult SWSSConsumerStateTable_getFd(SWSSConsumerStateTable tbl, int32_t *outFd);
3030

3131
// Block until data is available to read or until a timeout elapses.
3232
// A timeout of 0 means the call will return immediately.

common/c-api/subscriberstatetable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ SWSSResult SWSSSubscriberStateTable_pops(SWSSSubscriberStateTable tbl,
3939
});
4040
}
4141

42-
SWSSResult SWSSSubscriberStateTable_getFd(SWSSSubscriberStateTable tbl, uint32_t *outFd) {
43-
SWSSTry(*outFd = numeric_cast<uint32_t>(((SubscriberStateTable *)tbl)->getFd()));
42+
SWSSResult SWSSSubscriberStateTable_getFd(SWSSSubscriberStateTable tbl, int32_t *outFd) {
43+
SWSSTry(*outFd = ((SubscriberStateTable *)tbl)->getFd());
4444
}
4545

4646
SWSSResult SWSSSubscriberStateTable_readData(SWSSSubscriberStateTable tbl, uint32_t timeout_ms,

common/c-api/subscriberstatetable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ SWSSResult SWSSSubscriberStateTable_pops(SWSSSubscriberStateTable tbl,
2828
// Callers must NOT read/write on the fd, it may only be used for epoll or similar.
2929
// After the fd becomes readable, SWSSSubscriberStateTable_readData must be used to
3030
// reset the fd and read data into internal data structures.
31-
SWSSResult SWSSSubscriberStateTable_getFd(SWSSSubscriberStateTable tbl, uint32_t *outFd);
31+
SWSSResult SWSSSubscriberStateTable_getFd(SWSSSubscriberStateTable tbl, int32_t *outFd);
3232

3333
// Block until data is available to read or until a timeout elapses.
3434
// A timeout of 0 means the call will return immediately.

common/c-api/zmqconsumerstatetable.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ SWSSResult SWSSZmqConsumerStateTable_pops(SWSSZmqConsumerStateTable tbl,
3535
});
3636
}
3737

38-
SWSSResult SWSSZmqConsumerStateTable_getFd(SWSSZmqConsumerStateTable tbl, uint32_t *outFd) {
39-
SWSSTry(*outFd = numeric_cast<uint32_t>(((ZmqConsumerStateTable *)tbl)->getFd()));
38+
SWSSResult SWSSZmqConsumerStateTable_getFd(SWSSZmqConsumerStateTable tbl, int32_t *outFd) {
39+
SWSSTry(*outFd = ((ZmqConsumerStateTable *)tbl)->getFd());
4040
}
4141

4242
SWSSResult SWSSZmqConsumerStateTable_readData(SWSSZmqConsumerStateTable tbl, uint32_t timeout_ms,

common/c-api/zmqconsumerstatetable.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ SWSSResult SWSSZmqConsumerStateTable_pops(SWSSZmqConsumerStateTable tbl,
2929
// Callers must NOT read/write on fd, it may only be used for epoll or similar.
3030
// After the fd becomes readable, SWSSZmqConsumerStateTable_readData must be used to
3131
// reset the fd and read data into internal data structures.
32-
SWSSResult SWSSZmqConsumerStateTable_getFd(SWSSZmqConsumerStateTable tbl, uint32_t *outFd);
32+
SWSSResult SWSSZmqConsumerStateTable_getFd(SWSSZmqConsumerStateTable tbl, int32_t *outFd);
3333

3434
// Block until data is available to read or until a timeout elapses.
3535
// A timeout of 0 means the call will return immediately.

crates/swss-common/src/types/consumerstatetable.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,17 @@ impl ConsumerStateTable {
3838
// as long as the DbConnector does.
3939
unsafe {
4040
let fd = swss_try!(p_fd => SWSSConsumerStateTable_getFd(self.ptr, p_fd))?;
41-
let fd = BorrowedFd::borrow_raw(fd.try_into().unwrap());
41+
if fd == -1 {
42+
return Err(Exception::new("Invalid file descriptor: -1"));
43+
}
44+
let fd = BorrowedFd::borrow_raw(fd);
4245
Ok(fd)
4346
}
4447
}
4548

4649
pub fn read_data(&self, timeout: Duration, interrupt_on_signal: bool) -> Result<SelectResult> {
47-
let timeout_ms = timeout.as_millis().try_into().unwrap();
50+
let timeout_ms: u32 = timeout.as_millis().try_into()
51+
.map_err(|_| Exception::new("Invalid timeout value"))?;
4852
let res = unsafe {
4953
swss_try!(p_res => {
5054
SWSSConsumerStateTable_readData(self.ptr, timeout_ms, interrupt_on_signal as u8, p_res)
@@ -68,7 +72,11 @@ impl ConsumerStateTable {
6872

6973
impl Drop for ConsumerStateTable {
7074
fn drop(&mut self) {
71-
unsafe { swss_try!(SWSSConsumerStateTable_free(self.ptr)).expect("Dropping ConsumerStateTable") };
75+
unsafe {
76+
if let Err(e) = swss_try!(SWSSConsumerStateTable_free(self.ptr)) {
77+
eprintln!("Error dropping ConsumerStateTable: {}", e);
78+
}
79+
}
7280
}
7381
}
7482

crates/swss-common/src/types/dbconnector.rs

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -208,20 +208,13 @@ impl DbConnector {
208208
}
209209
}
210210

211-
impl Clone for DbConnector {
212-
/// Clone with a default timeout of 15 seconds.
213-
///
214-
/// 15 seconds was picked as an absurdly long time to wait for Redis to respond.
215-
/// Panics after a timeout, or if any other exception occurred.
216-
/// Use `clone_timeout` for control of timeout and exception handling.
217-
fn clone(&self) -> Self {
218-
self.clone_timeout(15000).expect("DbConnector::clone failed")
219-
}
220-
}
221-
222211
impl Drop for DbConnector {
223212
fn drop(&mut self) {
224-
unsafe { swss_try!(SWSSDBConnector_free(self.ptr)).expect("Dropping DbConnector") };
213+
unsafe {
214+
if let Err(e) = swss_try!(SWSSDBConnector_free(self.ptr)) {
215+
eprintln!("Error dropping DbConnector: {}", e);
216+
}
217+
}
225218
}
226219
}
227220

@@ -245,5 +238,4 @@ impl DbConnector {
245238
async_util::impl_basic_async_method!(hgetall_async <= hgetall(&self, key: &str) -> Result<HashMap<String, CxxString>>);
246239
async_util::impl_basic_async_method!(hexists_async <= hexists(&self, key: &str, field: &str) -> Result<bool>);
247240
async_util::impl_basic_async_method!(flush_db_async <= flush_db(&self) -> Result<bool>);
248-
async_util::impl_basic_async_method!(clone_async <= clone(&self) -> Self);
249241
}

crates/swss-common/src/types/exception.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,36 @@ impl Exception {
5959
}
6060
}
6161

62+
/// Create a new Exception with a custom message (for Rust-side errors).
63+
/// Automatically captures the caller's file and line number using `#[track_caller]`.
64+
///
65+
/// # Example
66+
/// ```
67+
/// use swss_common::{Exception, Result};
68+
///
69+
/// fn validate_fd(fd: i32) -> Result<()> {
70+
/// if fd < 0 {
71+
/// return Err(Exception::new("Invalid file descriptor"));
72+
/// }
73+
/// Ok(())
74+
/// }
75+
///
76+
/// // The exception will automatically include the location where it was created:
77+
/// let result = validate_fd(-1);
78+
/// assert!(result.is_err());
79+
/// let err = result.unwrap_err();
80+
/// assert_eq!(err.message(), "Invalid file descriptor");
81+
/// // err.location() will be something like "src/types/exception.rs:70"
82+
/// ```
83+
#[track_caller]
84+
pub fn new(message: impl Into<String>) -> Self {
85+
let location = std::panic::Location::caller();
86+
Self {
87+
message: message.into(),
88+
location: format!("{}:{}", location.file(), location.line()),
89+
}
90+
}
91+
6292
/// Get an informational string about the error that occurred.
6393
pub fn message(&self) -> &str {
6494
&self.message

crates/swss-common/src/types/producerstatetable.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ impl ProducerStateTable {
5858

5959
impl Drop for ProducerStateTable {
6060
fn drop(&mut self) {
61-
unsafe { swss_try!(SWSSProducerStateTable_free(self.ptr)).expect("Dropping ProducerStateTable") };
61+
unsafe {
62+
if let Err(e) = swss_try!(SWSSProducerStateTable_free(self.ptr)) {
63+
eprintln!("Error dropping ProducerStateTable: {}", e);
64+
}
65+
}
6266
}
6367
}
6468

0 commit comments

Comments
 (0)