Linting: Disallow unwraps, replace with expect or error propagation#868
Linting: Disallow unwraps, replace with expect or error propagation#868tnull merged 9 commits intolightningdevkit:mainfrom
unwraps, replace with expect or error propagation#868Conversation
|
👋 Thanks for assigning @joostjager as a reviewer! |
a05b2b6 to
2eb9f09
Compare
|
🔔 1st Reminder Hey @joostjager! This PR has been waiting for your review. |
|
🔔 2nd Reminder Hey @joostjager! This PR has been waiting for your review. |
2eb9f09 to
374b732
Compare
|
Rebased to address minor conflict. |
src/chain/bitcoind.rs
Outdated
| // wait on the result before proceeding. | ||
| { | ||
| let mut status_lock = self.wallet_polling_status.lock().unwrap(); | ||
| let mut status_lock = self.wallet_polling_status.lck(); |
There was a problem hiding this comment.
I don't like this much, renaming methods on data types that are very famliar.
There was a problem hiding this comment.
Yeah, I usually follow the same train of thought, however, in this case it also leads us to the anti-pattern of sprinkling unwrap everywhere. We could replace them with except("lock") or something like this, but this would make it even more verbose everywhere. Hence why I opted to go this way, which even reduces clutter everywhere.
Let me know if you deem this a blocker though, happy to revert that commit and go the cluttered route if you prefer.
There was a problem hiding this comment.
Would it be possible to do add-on a lock-specific expect method, as a middle road?
Otherwise it might be good to ask a second reviewer for their opinion. This is quite a visible thing.
There was a problem hiding this comment.
Would it be possible to do add-on a lock-specific expect method, as a middle road?
I'm not quite sure I understand what you mean by that? Anything different than expect("lock") I mentioned above?
There was a problem hiding this comment.
I was thinking something like
trait LockResultExt<T> {
fn expect_not_poisoned(self) -> T;
}
impl<T> LockResultExt<MutexGuard<'_, T>> for LockResult<MutexGuard<'_, T>> {
fn expect_not_poisoned(self) -> MutexGuard<'_, T> {
self.expect("mutex poisoned")
}
}
impl<T> LockResultExt<RwLockReadGuard<'_, T>> for LockResult<RwLockReadGuard<'_, T>> {
fn expect_not_poisoned(self) -> RwLockReadGuard<'_, T> {
self.expect("rwlock poisoned")
}
}
impl<T> LockResultExt<RwLockWriteGuard<'_, T>> for LockResult<RwLockWriteGuard<'_, T>> {
fn expect_not_poisoned(self) -> RwLockWriteGuard<'_, T> {
self.expect("rwlock poisoned")
}
}
Usage: self.wallet_polling_status.lock().expect_not_poisoned()
There was a problem hiding this comment.
Decidedly didn't go this way to keep it as brief as possible. Anyways, now switched to use expect for locks also.
There was a problem hiding this comment.
Don't mind the duplication of the panic string really, only wanted to suggest something more in the direction of what you had initially.
4cddaf8 to
8422182
Compare
|
Addressed feedback so far. |
0b515fa to
d8cb8c6
Compare
We replace all `unwrap`s with `expect`s. Co-Authored-By: HAL 9000
Log and skip runtime listener failures instead of panicking when accepting inbound connections or converting accepted sockets. These errors can happen in normal operation, so keeping the node running is safer than treating them as unreachable. Co-Authored-By: HAL 9000
Replace the success-path unwrap on payment amounts with an expect that explains why outbound payments must already have a recorded amount by the time LDK reports them as sent. Co-Authored-By: HAL 9000
Replace the pending-channel unwrap with an expect that records why supported LDK Node state should always include the former temporary channel id. Older rust-lightning state could omit it, but LDK Node never shipped before that field existed. Co-Authored-By: HAL 9000 Signed-off-by: Elias Rohrer <dev@tnull.de>
Replace the user_version query unwrap with normal io::Error propagation so database initialization failures are reported cleanly instead of panicking. Co-Authored-By: HAL 9000
Replace the Tokio runtime builder unwrap with io::Error propagation so VSS startup failures surface through the constructor instead of panicking. Co-Authored-By: HAL 9000
Use a zero-millisecond fallback for elapsed-time logging so clock adjustments do not panic the chain polling loop. Co-Authored-By: HAL 9000
Return Esplora client construction failures through build-time error handling instead of panicking so invalid headers or reqwest setup errors fail node construction cleanly. Co-Authored-By: HAL 9000
Fail library clippy runs when new unwrap calls are introduced so the unwrap policy stays enforced without pulling tests, benches, or docs into the restriction. Co-Authored-By: HAL 9000 Signed-off-by: Elias Rohrer <dev@tnull.de>
d8cb8c6 to
ad04cfc
Compare
|
Now switched away from the custom lock extensions and to just using |
| writer.log(record); | ||
|
|
||
| assert_eq!(*log.lock().unwrap(), "Test message (ch:abcdef p:02abcd)"); | ||
| assert_eq!(*log.lock().expect("lock"), "Test message (ch:abcdef p:02abcd)"); |
There was a problem hiding this comment.
I don't think the test code is passed through the linter. It doesn't hurt, but also doesn't add much here.
For the longest time we wanted to enforce clear rules around
unwrapuse. Here we finally do that:Mutex/RwLocklocking toExthelpers that avoid theunwrapand are shorter, reducing clutter in codeunwraps to useexpects, providing clear rationale why they are deemed unreachableunwraps throughclippyin CI (in non-test/documentation code, that is)