I have a object which has a Drop impl which performs a, maybe failing, action. Is there a possibility to return a error condition somehow?
panic! is a bit too aggressive for this purpose, as it's not uncommon that the action fails.
The object is sharing a ctx struct, I thought of setting an error flag there which can be checked, just like C's errno. Is there some more elegant way or pattern of doing this? Perhaps by creating a proxy object on creation with which the error can be delivered?
In general it is not possible to return an error condition from drop. You can panic! or do a best effort cleanup and log an error message (or post it to some global channel).
However, if failure is not exceptionally rare, I would go for an explicit deallocation API along this lines
struct S {
destroyed: bool // false for new instances
}
impl S {
fn destroy(mut self) -> Result<()> { // takes self by value and hence can't be called twice
self.destoryed = true;
// do cleanup
}
}
impl Drop for S {
fn drop(&mut self) {
if !self.destroyed {
panic!("not destroyed S instance found!"); // or may be `error!(...)`
}
}
}
The value of the Drop trait is in its implicitness, so it's inherently somewhat at odds with error handling, which Rust philosophy is to make explicit. For protecting a dynamic scope, @gkoz's answer would be a decent idea.
Explicit drop functions would work well if we had a way to prevent you from leaving off the drop call (and getting a compiler-generated call to the implicit drop). Is RFC: Add linear type facility · Issue #814 · rust-lang/rfcs · GitHub still the most current proposal for that? Anyway, we can't prevent dropping entirely because the thread might be in the middle of a panic.