Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[ProgressBar] Empty iterable throws Exception on "maximum number of steps is not set" #47244

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
freimair opened this issue Aug 10, 2022 · 7 comments · Fixed by #52605
Closed

Comments

@freimair
Copy link
Contributor

freimair commented Aug 10, 2022

Symfony version(s) affected

latest

Description

I stumbled upon an empty array that has been used with a progress bar. And my execution stopped. Turns out the ProgressBar checks if its max steps are set when "remaining" and "estimated" values are used in formatting. Nothing wrong so far.

However, in case there is an empty array supplied to the progress bar, code internals interpret a max value of 0 as the max value not being set:

                if (!$bar->getMaxSteps()) {
                    throw new LogicException('Unable to display the ... if the maximum number of steps is not set.');
                }

(https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L522 and https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L529)

That to me seems not entirely accurate. Because in this very case, the max value IS set and it IS 0. Yet, it is treated like it is NOT set.

Expected:
I would expect the progress bar not to fail if an empty Iterable is presented to it.

How to reproduce

$progressBar = new ProgressBar(new ConsoleOutput(OutputInterface::VERBOSITY_DEBUG);
$progressBar->setFormat('debug');

// this very array sources somewhere in a bigger project and it just happens to be empty some times
$incoming = array();

foreach($progressBar->iterate($incoming) as $current) {
   var_dump($current);
}

Possible Solution

Changing the line mentioned above:

                if (!$bar->getMaxSteps()) {
                    throw new LogicException('Unable to display the ... if the maximum number of steps is not set.');
                }

(https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L522 and https://github.com/symfony/symfony/blob/6.2/src/Symfony/Component/Console/Helper/ProgressBar.php#L529)

to

                if (!isset($bar->max)) {
                    throw new LogicException('Unable to display the ... if the maximum number of steps is not set.');
                }

seem to be semantically more correct. And it makes the ProgressBar behave like I expected it to do. If you guys are ok with this approach, I can provider a PR.

Additional Context

No response

Thanks!

@xabbuh
Copy link
Member

xabbuh commented Aug 11, 2022

null !== $bar->max seems to be the way to go at the places you mention to me. However, we will need to dig a bit deeper if there aren't any further issues with the $max property being zero. For example if I read the code correctly, in getEstimated() we will then divide by zero.

@freimair
Copy link
Contributor Author

I am not entirely sure why you want to invert the null-check because the exception is thrown in case $bar->max IS null or 0 (I enlarged the code samples a bit to show more context). Thus, I would expect to do the check like null === $bar->max.

Second, are you opting for the === operator to purposefully generate a warning in case $this->max has no value assigned?

As for digging a bit deeper: of course.

@carsonbot
Copy link

Hey, thanks for your report!
There has not been a lot of activity here for a while. Is this bug still relevant? Have you managed to find a workaround?

@freimair
Copy link
Contributor Author

freimair commented Mar 2, 2023

waiting for review of the PR #47259

@carsonbot carsonbot removed the Stalled label Mar 2, 2023
@carsonbot
Copy link

Hey, thanks for your report!
There has not been a lot of activity here for a while. Is this bug still relevant? Have you managed to find a workaround?

@carsonbot
Copy link

Friendly ping? Should this still be open? I will close if I don't hear anything.

@freimair
Copy link
Contributor Author

waiting for review of the PR #47259

@carsonbot carsonbot removed the Stalled label Sep 22, 2023
@fabpot fabpot closed this as completed Nov 16, 2023
fabpot added a commit that referenced this issue Nov 16, 2023
…ray (GromNaN)

This PR was merged into the 7.1 branch.

Discussion
----------

[Console] Support `ProgressBar::iterate()` on empty array

| Q             | A
| ------------- | ---
| Branch?       | 6.4
| Bug fix?      | yes
| New feature?  | no
| Deprecations? | no
| Issues        | Fix #47244
| License       | MIT

Alternative to #47259

Use `$max = null` to indicate that the value is unknown. This allows `0` to be displayed by directly setting the progress bar to 100%.

Zero is only supported for `iterate()`. When passed to the constructor or `setMaxSteps`, it means "unknown max".

Commits
-------

574b8a3 Fix ProgressBar::iterate on empty iterator
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants