Unsatisfactory error recovery story with `Response::end()`
abonander opened this issue · comments
If Response::end()
fails, the response is consumed so there's no way to create a NickelError
without unsafe
(except that NickelError
has all fields public so it's possible to bypass the constructor completely). The reasoning for unsafe
on NickelError::without_response()
talks about deadlock if the response is not flushed, which is what the user is trying to do by calling Response::end()
. So if the flush fails, what are we meant to do? It seems like a guaranteed deadlock since we can't call bail()
now.
After some thought, it's occurred to me that Response::end()
isn't meant to be called in client code. This should be documented on the method or it should be hidden entirely or marked pub(crate)
.
I suspect you are right. It looks like it is just called by the Response::bail()
method, and maybe should just be inlined there. Alternatively, it could just as easily take a &self
. It is not necessary to consume the response since all it does is flush the underlying hyper Response
.
I think you're both correct, it existed before pub(crate)
was an option and I also think it might not be as necessary anymore now, it used to be that dropping the Response
would mean the connection would hang but hyper was updated to do the right thing on drop
. As for NickelError::without_responsebeing unsafe, forcing the user to always return *something* which contained the response stream was the idea behind it and it's only really still a problem if they
mem::forget` the Response I think which may lead to the hung stream... not sure if timeouts handle that now or not.