psalm-plugin-laravel icon indicating copy to clipboard operation
psalm-plugin-laravel copied to clipboard

How to Supress PossiblyInvalidArgument for Request Objects?

Open deleugpn opened this issue 6 years ago • 6 comments

Laravel has Form Request classes that can look like the following:

<?php

namespace App\Modules\Accounts\Requests;

use App\Http\Requests\FormRequest;

class SaveAccountRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'string|max:128',
            'email' => 'required|string|email',
        ];
    }

    public function email(): string
    {
        return $this->input('email');
    }
}

The input() method has a return signature declared as * @return string|array|null. For that reason, Psalm end up giving PossiblyInvalidArgument [...] possibly different type array<array-key, mixed>|string|null provided.

I tried the following:

    <issueHandlers>
        <PossiblyInvalidArgument>
            <errorLevel type="suppress">
                <file name="*Request.php" />
            </errorLevel>
        </PossiblyInvalidArgument>
    </issueHandlers>

but that configuration leads to

/app # vendor/bin/psalm
Could not resolve config path to /app//*Request.php

What can I do to suppress this problem but only for Request objects or for any interaction with the input method of a Form Request class?

deleugpn avatar Mar 08 '19 22:03 deleugpn

You'll want to use <file name="**/*Request.php" /> or <file name="**/**/*Request.php" /> as appropriate given the nesting of those files in your file system.

muglug avatar Mar 11 '19 05:03 muglug

But really the plugin should be able to interpret the rules in a given class.

muglug avatar Mar 11 '19 05:03 muglug

That could get tricky as Laravel supports custom rules and require_if / require_with, etc. Maybe limit to support only the basic rules might be a sane option.

deleugpn avatar Mar 11 '19 09:03 deleugpn

@deleugpn I'm wondering if you still have this issue?

If so, I would recommend checking if you could declare your request attributes as @propertys (that's how I do it):

<?php

namespace App\Modules\Accounts\Requests;

use App\Http\Requests\FormRequest;

/**
  * @property string|null $name
  * @property string $email
  */
class SaveAccountRequest extends FormRequest
{
    public function rules()
    {
        return [
            'name' => 'string|max:128',
            'email' => 'required|string|email',
        ];
    }
}

PS: Make sure to enable usePhpDocPropertiesWithoutMagicCall="true" in your psalm.xml.dist (or psalm.xml).

caugner avatar Jul 13 '21 10:07 caugner

I gave up on using Psalm, sorry.

deleugpn avatar Jul 13 '21 10:07 deleugpn

I'm sorry to hear that, but maybe you might want to give it another try in about one month?

These days, I have resolved a couple of annoying issues, and I'm committed to fixing any other issues you will have.

caugner avatar Jul 13 '21 11:07 caugner