Skip to content
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

Confusion about inline @throws void and implicitThrows #5364

Closed
asherkin opened this issue Jul 22, 2021 · 3 comments
Closed

Confusion about inline @throws void and implicitThrows #5364

asherkin opened this issue Jul 22, 2021 · 3 comments

Comments

@asherkin
Copy link
Contributor

Bug report

void gets treated as if it was an exception type when used in an inline @throws annotation with PHPStan 0.12.93.

Code snippet that reproduces the problem

https://phpstan.org/r/dfc16fcc-4b54-41c0-a515-3795abe04f6b

Doesn't repro on phpstan.org due to needing checked exceptions config:

parameters:
    implicitThrows: false
    exceptions:
        check:
            missingCheckedExceptionInThrows: true
            tooWideThrowType: true

Running it locally produces:

 ------ --------------------------------------------------------------------------------------------------
  Line   test.php
 ------ --------------------------------------------------------------------------------------------------
  12     Function call_test() throws checked exception void but it's missing from the PHPDoc @throws tag.
 ------ --------------------------------------------------------------------------------------------------

Expected output

My expectation based on https://phpstan.org/blog/bring-your-exceptions-under-control is that the inline @throws annotation will supress test()'s annotation (which obviously doesn't make sense in this small example), and because we've got implicitThrows: false should match up with the calling function's expected exceptions (none).

The main driver behind this was supressing an error where I know the code meets the invariants required to not throw an exception. While writing this up I've realised I should probably actually just put it in a try..catch that throws a unchecked exception (sadly redesigning the API to be "safe" isn't possible), but I still think the behaviour here is counter to expectations.

p.s. What's your thoughts on LogicException? Checked or unchecked?

Did PHPStan help you today? Did it make you happy in any way?

Yes! I recently embarked on some refactoring work to change a very fundamental "operate on one thing" to "operate on many things". PHPStan's excellent static analysis meant that once I'd changed the entry point, the type checks failing bubbled down to the rest of the code base and highlighted every single place that needed to be updated. I'd estimated this work as taking around 10 days based on similar refactoring done in the past on similarly complex code, but thanks to having PHPStan setup in this project it only took 2 days of work (and I've been able to spend some time focusing on exception safety!)

@ondrejmirtes
Copy link
Member

Thank you for your kind words!

The main driver behind this was supressing an error where I know the code meets the invariants required to not throw an exception

Have you considered dynamic throw type extension? https://phpstan.org/developing-extensions/dynamic-throw-type-extensions

p.s. What's your thoughts on LogicException? Checked or unchecked?

Looks like PHP convention is to have RuntimeException as checked, and LogicException as unchecked (but it wasn't intuitive to me either): #5034

The reported bug is fixed: phpstan/phpstan-src@da3790e

@asherkin
Copy link
Contributor Author

The main driver behind this was supressing an error where I know the code meets the invariants required to not throw an exception

Have you considered dynamic throw type extension? https://phpstan.org/developing-extensions/dynamic-throw-type-extensions

That looks like exactly what I needed, thanks!

p.s. What's your thoughts on LogicException? Checked or unchecked?

Looks like PHP convention is to have RuntimeException as checked, and LogicException as unchecked (but it wasn't intuitive to me either): #5034

Thanks - that relation is what I expected as well, so that's good to know. I was surprised to find that PHPStorm has both RuntimeException and LogicException as unchecked by default.

The reported bug is fixed: phpstan/phpstan-src@da3790e

❤️

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Aug 23, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants