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

[7.x] Throw a TypeError if concrete is not a string or closure #33539

Merged
merged 3 commits into from Jul 21, 2020

Conversation

mr-feek
Copy link
Contributor

@mr-feek mr-feek commented Jul 14, 2020

There is currently an assumption that if the concrete parameter passed to bind is not a Closure, then it is a string. Let's fail loudly if that is not the case.

Problem surfaced here: facade/ignition#291

Copy link
Member

@GrahamCampbell GrahamCampbell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

phpdoc says null is allowed, but your PR doesn't allow it

src/Illuminate/Container/Container.php Outdated Show resolved Hide resolved
src/Illuminate/Container/Container.php Outdated Show resolved Hide resolved
src/Illuminate/Container/Container.php Outdated Show resolved Hide resolved
src/Illuminate/Container/Container.php Outdated Show resolved Hide resolved
src/Illuminate/Container/Container.php Show resolved Hide resolved
@mr-feek
Copy link
Contributor Author

mr-feek commented Jul 14, 2020

phpdoc says null is allowed, but your PR doesn't allow it

I'm not sure how $concrete could be null here, considering it is set to $abstract if it is null in the few lines above.

@mr-feek
Copy link
Contributor Author

mr-feek commented Jul 14, 2020

Would you like me to squash or do you squash when merging?

@mr-feek mr-feek changed the title [7.x] Throw an invalid argument exception if concrete is not a string or closure [7.x] Throw a TypeError if concrete is not a string or closure Jul 14, 2020
@GrahamCampbell
Copy link
Member

Don't worry about that. Taylor can squash (or not) if he wants. :)

@mr-feek
Copy link
Contributor Author

mr-feek commented Jul 14, 2020

Thanks for the feedback @GrahamCampbell , it's appreciated 🤝

@@ -234,6 +234,10 @@ public function bind($abstract, $concrete = null, $shared = false)
// bound into this container to the abstract type and we will just wrap it
// up inside its own Closure to give us more convenience when extending.
if (! $concrete instanceof Closure) {
if (! is_string($concrete)) {
throw new \TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note for Taylor: This error message format is what PHP 8.0 does when there's a genuine union type.

@taylorotwell
Copy link
Member

We may just eventually use a real union type here.

@GrahamCampbell
Copy link
Member

@taylorotwell the reason for this PR was to stop real bugs, not just to add a type for the sake of it.

@mr-feek
Copy link
Contributor Author

mr-feek commented Jul 19, 2020

I have to agree with @GrahamCampbell here -- this issue took me several hours to realize. Even if we decide to use a real union type here in the future, I strongly believe it would be beneficial to add this validation now.

@taylorotwell taylorotwell reopened this Jul 21, 2020
@taylorotwell taylorotwell merged commit a66caa5 into laravel:7.x Jul 21, 2020
@ssmusoke
Copy link

Not sure what I need to do, but it seems that this PR has created all sorts of bind errors not sure how to resolve them for example when I run php artisan migrate

` TypeError

Illuminate\Container\Container::bind(): Argument #2 ($concrete) must be of type Closure|string|null

at vendor/laravel/framework/src/Illuminate/Container/Container.php:238
234| // bound into this container to the abstract type and we will just wrap it
235| // up inside its own Closure to give us more convenience when extending.
236| if (! $concrete instanceof Closure) {
237| if (! is_string($concrete)) {

238| throw new \TypeError(self::class.'::bind(): Argument #2 ($concrete) must be of type Closure|string|null');
239| }
240|
241| $concrete = $this->getClosure($abstract, $concrete);
242| }

  +10 vendor frames 

11 artisan:37
Illuminate\Foundation\Console\Kernel::handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
`

@GrahamCampbell
Copy link
Member

This is because there's a mistake in your code, which is now being caught and showed to you. That was the exact purpose of this. PR. :)

@GrahamCampbell
Copy link
Member

Can you show the whole stack trace?

@ssmusoke
Copy link

That is all the stack trace that I get, I do not know which migration has the issue since it is not highlighted

@GrahamCampbell
Copy link
Member

If you run the command in verbose mode, more should show. -vv

@ssmusoke
Copy link

I get the same output

My environment is

PHP 7.3.20 (cli) (built: Jul 9 2020 23:50:54) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.20, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.3.20, Copyright (c) 1999-2018, by Zend Technologies

@GrahamCampbell
Copy link
Member

php artisan migrate -vv

@dkulyk
Copy link
Contributor

dkulyk commented Jul 28, 2020

You should use $app->instance(Service::class, $serviceInstance) instead $app->bind(Service::class, $serviceInstance)

@ssmusoke
Copy link

Tried that and php artisan --vv migrate

Interesting I have these two dependencies

"laravel/framework": "^7.0",
"laravel/nova": "^3.0"

php artisan -vv nova:publish gives the same error, so I am suspecting that the issue may be within artisan command

@GrahamCampbell
Copy link
Member

php artisan -vv nova:publish gives the same error, so I am suspecting that the issue may be within artisan command

I don't think so. The issue will be in one of your service providers, or possibly one provided in the core. Please show us the stack trace, or this will never be fixed (we can only fix it if we know where it is).

@ssmusoke
Copy link

ssmusoke commented Jul 28, 2020

Maybe my composer.json may help

{
"name": "laravel/laravel",
"type": "project",
"description": "The Laravel Framework.",
"keywords": [ "framework", "laravel" ],
"license": "MIT",
"require": {
"php": "^7.3",
"doctrine/dbal": "^2.10",
"facade/ignition": "^2.0",
"fideloper/proxy": "^4.0",
"intervention/image": "~2.4",
"kalnoy/nestedset": "^5.0",
"laravel/framework": "^7.0",
"laravel/nova": "^3.0",
"laravel/telescope": "^3.5",
"laravel/tinker": "^2.0",
"league/flysystem-aws-s3-v3": "^1.0",
"maatwebsite/excel": "^3.1",
"maatwebsite/laravel-nova-excel": "^1.2",
"orlyapps/nova-belongsto-depend": "^2.0",
"pragmarx/health": "^0.10.2",
"reportico/laravel-reportico": "^7.0",
"rap2hpoutre/laravel-log-viewer": "^1.6",
"spatie/laravel-backup": "^6.8",
"spatie/laravel-medialibrary": "^7.0.0",
"spatie/laravel-permission": "^3.10",
"spatie/nova-backup-tool": "^4.0",
"themsaid/wink": "^1.0",
"titasgailius/search-relations": "^1.0",
"twilio/sdk": "^5.39",
"tymon/jwt-auth": "dev-develop",
"vyuldashev/nova-permission": "^2.5"
},
"require-dev": {
"arrilot/laravel-data-anonymization": "^1.1",
"barryvdh/laravel-ide-helper": "^2.6",
"beyondcode/laravel-dump-server": "^1.0",
"filp/whoops": "^2.0",
"fzaninotto/faker": "^1.4",
"laravel/ui": "^2.0",
"mockery/mockery": "^1.0",
"nunomaduro/collision": "^4.1",
"phpunit/phpunit": "^8.5",
"themsaid/laravel-mail-preview": "^3.0"
},
"config": {
"optimize-autoloader": true,
"preferred-install": "dist",
"sort-packages": true,
"post-update-cmd": [ "@php artisan nova:publish" ]
},
"extra": {
"laravel": {
"dont-discover": []
}
},
"autoload": {
"psr-4": {
"App\": "app/"
},
"classmap": [ "database/seeds", "database/factories", "database/anonymization" ]
},
"autoload-dev": {
"psr-4": {
"Tests\": "tests/"
}
},
"minimum-stability": "dev",
"prefer-stable": true,
"scripts": {
"post-autoload-dump": [
"Illuminate\Foundation\ComposerScripts::postAutoloadDump",
"@php artisan package:discover --ansi"
],
"post-root-package-install": [ "@php -r "file_exists('.env') || copy('.env.example', '.env');"" ],
"post-create-project-cmd": [ "@php artisan key:generate --ansi" ],
"post-update-cmd": [ "@php artisan nova:publish", "@reportico-configure-auth" ],
"reportico-configure-auth": ["php -r "copy('work/ReporticoServiceProvider.php', 'vendor/reportico/laravel-reportico/src/Reportico/Reportico/ReporticoServiceProvider.php');""]
},
"repositories": [
{
"type": "composer",
"url": "https://nova.laravel.com"
}
]
}

@mr-feek
Copy link
Contributor Author

mr-feek commented Jul 28, 2020

What's your actual version of facade / ignition? If you look at my original PR description, you'll see this was actually as a result of a bug in facade/ignition which I fixed in the latest release. Please try updating it.

Otherwise we are just speculating without seeing a full stack trace.

@ssmusoke
Copy link

Thank you very much for your patience, I was only looking at the console for the error message, forgetting the logs

I found that the pragmarx/health dependency was the one causing the closure issue. I will go ahead and open an issue there

@AustinW
Copy link
Contributor

AustinW commented Jul 28, 2020

Thank you very much for your patience, I was only looking at the console for the error message, forgetting the logs

I found that the pragmarx/health dependency was the one causing the closure issue. I will go ahead and open an issue there

I was having the same issue and also have that package installed. Thank you!

eronisko added a commit to SlovakNationalGallery/register-architektury that referenced this pull request Jan 22, 2021
eronisko added a commit to SlovakNationalGallery/register-architektury that referenced this pull request Jan 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants