I have a Rocket.rs server and in one of its routes, I'm calling a function that finds documents of a collection and loops over it.
Find documents of a collection:
let participations: Cursor<Document> = collection.aggregate(pipeline, None).await.expect("Failed to fetch documents.");
Now after fetching the documents, it returns a Cursor and then I call advance() on it to loop over the cursor. The problem arises while using is_ok() instead of expect() on advance() result value.
When doing this my code works fine without any errors.
while participations.advance().await.expect("Failed to advance.") {
let participation_doc = participations.deserialize_current();
}
But when I switch to this.
while participations.advance().await.is_ok() {
let participation_doc = participations.deserialize_current();
}
My code fails with an error.
thread 'rocket-worker-thread' panicked at 'called `Option::unwrap()` on a `None` value'
After debugging I found out that this error is encountered when calling participations.deserialize_current();. It throws an error because advance() call was not successful. But why my loop was executed in the first place if the advance() call was not successful is_ok() should've returned false. And why does my code work fine when using expect(). If there's an error then expect() should make my code panic.
What I want is my code to not panic even if advance() fails that's why I was using is_ok(). Any help would be appreciated.
As the comments have pointed out, you didn't specify which library this
advance()call comes from, but I'm assuming it isCursor::advancefrom MongoDB.The signature of that method is:
So, it is an asynchronous method which will either give you a Boolean, or a MongoDB error. As the docs say:
By awaiting, you get a value of
mongodb::error::Result<bool>. Then, you do two different things with it in your code snippets:result.expect("Failed to advance.")(similar toresult.unwrap())Here, you are saying "assume there was no MongoDB error (or else panic), then check whether there are more values available".
result.is_ok()Here, you are saying "check whether there was a MongoDB error".
Notice that in the second case, you are not actually using the Boolean value. (Did the compiler not warn you about this by any chance?) Maybe the API could be designed a bit better, but the first variant is slightly better. If you also want to gracefully handle errors, you want to check both that there is no MongoDB error, and that there are more values available from the
Cursor.Something like this: