Skip to content

When exceptions check is turned on, phpstan doesn't identifies the exception thrown correctly #11900

@zsolt0005

Description

@zsolt0005

Bug report

Playground doesn't allow me to turn on missingCheckedExceptionInThrows, so I can't include the playground results
Tested on versions: 1.10.3 and 1.12.7

Config

parameters:
  level: 8
  exceptions:
      check:
          tooWideThrowType: true
          missingCheckedExceptionInThrows: true

We need an exception class that can hold multiple exceptions inside. There is an abstract class that has some common functionality to minimalize duplications.

abstract class ADataException extends Exception
{
    protected int $exceptionsCount = 0;

    /**
     * @return void
     * @throws static
     */
    public function throwIfUsed(): void
    {
        if ($this->exceptionsCount > 0) {
            throw $this;
        }
    }

    final protected function setException(?Exception &$attribute, ?Exception $parameter): void
    {
        $isAttributeSet = ($attribute !== null);
        $isParameterSet = ($parameter !== null);

        $attribute = $parameter;

        if($isAttributeSet === $isParameterSet)
        {
            return;
        }

        if($isParameterSet)
        {
            $this->exceptionsCount++;
        }
        else
        {
            $this->exceptionsCount--;
        }
    }
}

An exception that extends that can look like this

final class TestDataException extends ADataException
{
    public ?Exception $invalidNumberException = null;

    public function setInvalidNumberException(?Exception $invalidNumberException): void
    {
        $this->setException($this->invalidNumberException, $invalidNumberException);
    }
}

Use case for validation for example

class TestPhpStan
{
    /**
     * @param int $number
     * @throws TestDataException
     */
    public function validate(int $number): void
    {
        $testDataException = new TestDataException();

        if($number < 1)
        {
            $testDataException->setInvalidNumberException(new Exception());
        }

        // Other checks that can set other exception inside the TestDataException

        $testDataException->throwIfUsed();
    }
}

This will result in the following error message:

Method CodeWars\Sub\TestPhpStan::validate() throws checked exception CodeWars\Sub\ADataException but it's missing from the PHPDoc @throws tag.

Code snippet that reproduces the problem

No response

Expected output

No error, valid code

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

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions