ext/ftp: throw an Error when ftp_nb_fget()/ftp_nb_fput() hit a busy connection - #23540
Conversation
|
Perhaps the code should be revised to throw an Error rather than returning false. Generally, Error is used to indicate a programming mistake, and this is the case here. I believe that's more appropriate than widening the return type |
|
cc @iliaal |
|
Agreed, |
ftp_nb_fget() and ftp_nb_fput() answered an already busy connection with a warning and false, against a declared int return type. Reaching that guard means a transfer was started from inside another transfer, which is a programming mistake, so throw an Error instead, as ftp_close() already does on the same in_use flag. The declarations stay int. The check stays ahead of the direction and closestream writes, so the running transfer is left untouched. The test reaches the guard through a stream wrapper that calls back into the extension mid transfer.
6a0827e to
fa921f8
Compare
ndossche
left a comment
There was a problem hiding this comment.
This is the right direction, but incomplete.
You should consistently do the same for ftp_nb_get & ftp_nb_put, such that this entire error class (which is rlly a programming error), can be handled in a consistent way.
The in_use guard is a programming error in all four non-blocking transfer functions, so all four now throw the same Error instead of two of them emitting a warning and returning false. ftp_nb_get() and ftp_nb_put() keep their int|false declaration, which is still returned when the local file cannot be opened. ftp_nb_put() closes the local stream before throwing, and the guards stay ahead of the direction/closestream writes, so a rejected re-entrant call leaves the running transfer untouched. ftp_nb_get_during_transfer.phpt and ftp_nb_get_during_nb_transfer.phpt asserted the old warning; they now record the Error and still assert that the outer transfer completes.
The test asserts the class it prints, so it must not presume Error in the catch: a change of thrown class has to fail the test rather than escape it.
Reworked as suggested: all four non-blocking transfer functions now throw the same
Erroron a busy connection, so the whole class is handled consistently.ftp_nb_get()andftp_nb_put()keep theirint|falsedeclaration —falseis still what they return when the local file cannot be opened — so there are no stub changes.The guards stay ahead of the
direction/closestreamwrites, andftp_nb_put()closes the local stream before throwing, so a rejected re-entrant call leaves the running transfer untouched.ftp_nb_get_during_transfer.phptandftp_nb_get_during_nb_transfer.phptasserted the old warning; they now record theErrorand still assert that the outer transfer completes.On the UPGRADING note: the phrase about the declared
intreturn type is gone. I kept the entry itself, because the warning-and-false behaviour did ship — thein_useguards are in 8.4.24 and 8.5.9 onwards, not master-only. Happy to drop it if you would still rather not carry the entry.