vimeo / psalm

A static analysis tool for finding errors in PHP applications
https://psalm.dev
MIT License
5.54k stars 660 forks source link

Throws types validation #2507

Open dbalabka opened 4 years ago

dbalabka commented 4 years ago

Recently, I have faced the problem that it is impossible to control what kind of exceptions may be thrown by interface implementations. It would be great to restrict to throw an exception that not declared in the interface doc block (or in any overrode method).

For example, Java supports the possibility to declare what exceptions can be thrown by the method using throws in the method declaration. Java also validates that the overridden method should throw only those exceptions that declared in the parent method or exceptions of compatible types.

In the following example, Psalm should point that WrongImplementation::get() throws an exception that isn't supported by the interface SomeInterface::get():

<?php

class SomeException extends Exception {}

interface SomeInterface
{
    /**
     * @throws SomeException
     */
    public function get() : int;
}

class WrongImplementation implements SomeInterface
{
    /**
     * {@inheritDoc}
     * @throws RuntimeException
     */
    public function get() : int
    {
        // ...
        throw new RuntimeException();
        // ...
    }
}

class CorrectImplementation implements SomeInterface
{
    /**
     * {@inheritDoc}
     */
    public function get() : int
    {
        // ...
        try {
            throw new RuntimeException();
        } catch (RuntimeException $e) {
            // we should wrap not supported exception
            throw new SomeException('', 0, $e);
        }
        return 0;
        // ...
    }
}

https://psalm.dev/r/ecf23dae78

Example of implementation: https://github.com/pepakriz/phpstan-exception-rules/blob/master/tests/src/Rules/data/throws-inheritance.php#L90

XedinUnknown commented 2 years ago

May be related to #6940.

XedinUnknown commented 2 years ago

Looks like @psalm-type declarations are not visible in @throws either.

Update: I see that I had actually been here before. Why was my comment marked as off-topic? Aren't the errors I am getting (crashing my builds) related to type validation in @throws?

Please, I would very much like to have this. Is there any plan or even intention? Is this a feature that is already decided to be OK?

psalm-github-bot[bot] commented 2 years ago

I found these snippets:

https://psalm.dev/r/70c8a71e28 ```php