Skip to content

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

Merged
taylorotwell merged 3 commits into
laravel:7.xfrom
mr-feek:7.x-bind-throw-invalid-argument
Jul 21, 2020
Merged

[7.x] Throw a TypeError if concrete is not a string or closure#33539
taylorotwell merged 3 commits into
laravel:7.xfrom
mr-feek:7.x-bind-throw-invalid-argument

Conversation

@mr-feek

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

Copy link
Copy Markdown
Contributor

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

@GrahamCampbell GrahamCampbell left a comment

Copy link
Copy Markdown
Collaborator

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

Comment thread src/Illuminate/Container/Container.php Outdated
Comment thread src/Illuminate/Container/Container.php Outdated
Comment thread src/Illuminate/Container/Container.php Outdated
Comment thread src/Illuminate/Container/Container.php Outdated
Comment thread src/Illuminate/Container/Container.php
@mr-feek

mr-feek commented Jul 14, 2020

Copy link
Copy Markdown
Contributor Author

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

mr-feek commented Jul 14, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown
Collaborator

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

@mr-feek

mr-feek commented Jul 14, 2020

Copy link
Copy Markdown
Contributor Author

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

// 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
Copy Markdown
Collaborator

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
Copy Markdown
Member

We may just eventually use a real union type here.

@GrahamCampbell

Copy link
Copy Markdown
Collaborator

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

@mr-feek

mr-feek commented Jul 19, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown

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
Copy Markdown
Collaborator

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
Copy Markdown
Collaborator

Can you show the whole stack trace?

@ssmusoke

Copy link
Copy Markdown

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
Copy Markdown
Collaborator

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

@ssmusoke

Copy link
Copy Markdown

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
Copy Markdown
Collaborator

php artisan migrate -vv

@dkulyk

dkulyk commented Jul 28, 2020

Copy link
Copy Markdown
Contributor

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

@ssmusoke

Copy link
Copy Markdown

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
Copy Markdown
Collaborator

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

ssmusoke commented Jul 28, 2020

Copy link
Copy Markdown

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

mr-feek commented Jul 28, 2020

Copy link
Copy Markdown
Contributor Author

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
Copy Markdown

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

AustinW commented Jul 28, 2020

Copy link
Copy Markdown
Contributor

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!

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.

6 participants