[Console] Default hidden question to 1 attempt for non-tty session #36590
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Problem 1
validateAttempts()
method repeats validation forever by default, until exception extendingRuntimeException
isn't thrown. This currently happens disregarding if user is in tty session where they can actually type input, or non-tty session. This presents a problem when user code throws custom exceptions for hidden questions -> loop doesn't stop. As far as I can tell this issue is in all Symfony versions, but it was uncovered only after we stopped marking interactive flag to false automatically ourselves. Actually, all 3 problems were already existing problems, just hidden until now.Problem 2
Infinite loop problem is related to hidden questions, but this one isn't. If validation fails, another attempt to read & validate happens. This means user will get two prompts: 2x same question with 2 different error messages. One error message coming from validator, second error message about inability to read input (because this loop repeats until this kind of error happens, so last output will always be this error). As an example, output in practice would look like following
So even if loop stops, output is more than expected.
Problem 3
This is purely cosmetic issue, but currently user gets
stty: stdin isn't a terminal
printed additionally when question helper tries to ask a hidden question without having tty. I have fixed this in same fashion as was already done for getShell() method.More details
Well root of the first problem is that
\Symfony\Component\Console\Helper\QuestionHelper::getHiddenResponse
is inconsistent. In some cases it does throwMissingInputException
(which extendsRuntimeException
), in others doesn't. This is because in others,shell_exec
is used, which won't returnfalse
even in non-tty sessions. Initially I attempted to fix this and make them consistent by checking for empty result +isTty
call, but during my testing I found that at least last,bash -c
method returns\n
as output both when passing empty input and when passing newline as input. This means we cannot differentiate with this technique when input is really empty, or at least I can't currently tell how, maybe someone does. I had also idea to use proc_open and check ifSTDERR
cotains message about stdin not being a terminal, but I realized these functions might not be available. In future we should modernize this method to use less hacky techniques. Other solutions, eg. Inquirer.js or hoa/console have much more elegant solutions. Anyway, since I encountered this issue and additionally this doesn't solve Problem 2, I stopped trying to fix this on this level.Alternative solution
Alternative solution to problem 1 and 3 would be to fallback to default in case of hidden questions when tty is missing. But this still doesn't solve problem 2 and I can't think about solution right now which would fix problem 2 separately. We also didn't really reach consensus if reading passwords via stdin is desired. I tried this in
Inquirer.js
and this library does read password from stdin