Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PhpStorm @throws tag in method calling other anonymous method

Tags:

php

phpstorm

I have a problem with PhpStorm @throws tag.

If created an static method for DB transaction:

/**
 * Performs a function in a transaction.
 *
 * @param callable $function Function to call.
 *
 * @throws \Throwable
 */
public static function transaction(callable $function) {...}

which is simply try which catches any on \Throwable and then rollback transactions on DB and rethrows \Throwable again.

The problem is that PhpStorm says the method transaction() throws \Throwable which is correct, so I put that tag in doc block, but in fact that \Throwable depends on parameter $function passed to method.

So when $function throws in fact for example ModelNotFoundException then transaction() also could only throws that ModelNotFoundException.

So when I create code like this:

function doSomething(SomeModelClass $model)
{
    Helper::transaction(function () use ($model) {
        $model->otherMethod();
        $model->methodThatCouldThrownAnModelNotFoundException();
        $model->otherMethod2();
        $model->otherMethodEtc();
    });
}

PhpStorm says that I need to add try and catch or throw tag. But it says that transaction throws \Throwable but in that case I could be more specific, because I know that it could be only ModelNotFoundException. But I cannot put it as @throws tag, because then PhpStorm will say, that trasaction could only throw \Throwable, so I need to remove that tag or add @throws ModelNotFoundException to transaction doc block.

In that when it will raise 2 warnings:

  1. PHPDoc comment doesn't contain all the necessary @throws tags
  2. Unhandled \Throwable.

For now I always add two simple lines with @noinspection tag:

/**
 * @throws ModelNotFoundException
 * @noinspection PhpDocMissingThrowsInspection
 */
function doSomething(SomeModelClass $model)
{
    /** @noinspection PhpUnhandledExceptionInspection */
    Helper::transaction(function () use ($model) {
        $model->otherMethod();
        $model->methodThatCouldThrownAnModelNotFoundException();
        $model->otherMethod2();
        $model->otherMethodEtc();
    });
}

I wonder if there is any way to associate the @throws tag in the transaction method with the @throws tag of the method sent as a parameter - $function, because it is tiresome to add these comments from noinspection every time this method is called.

like image 336
LordF Avatar asked Feb 22 '26 02:02

LordF


1 Answers

I wonder if there is any way to associate the @throws tag in the transaction method with the @throws tag of the method sent as a parameter - $function, because it is tiresome to add these comments from noinspection every time this method is called

There isn't or more correctly: none that I know about.

Here is what I know about:

  1. Unchecked Exceptions: Name those (generic) exceptions you don't need to check (configure to your benefit, unchecked exceptions are a common Phpstorm feature).
  2. Wrap and Bubble: As you turn any exception that happens when calling a function within a transaction into a transaction exception, create a more concrete TransactionException out of the throwable and pass the throwable as $previous to its constructor.

1. allows you to have unchecked exceptions, 2. allows you to have checked exceptions.


Usage Example:

Implement 2. Wrap and Bubble:

class TransactionFailedException extends RuntimeException
{}
/**
 * @throws TransactionFailedException
 */
public static function transaction(callable $function): void
{
    try {
        $function();
    } catch (Throwable $failure) {
        throw new TransactionFailedException('Transaction failed', 0, $failure);
    }
}

Then add TransactionFailedException to the unchecked exceptions (if still necessary, RuntimeException could be already in).

like image 156
hakre Avatar answered Feb 23 '26 16:02

hakre



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!