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

[5.8.13] 'SQLSTATE[HY000] [2002] Connection refused' if docktrine/dbal installed #28282

Closed
et-nik opened this issue Apr 20, 2019 · 18 comments

Comments

Projects
None yet
6 participants
@et-nik
Copy link

commented Apr 20, 2019

  • Laravel Version: 5.8.13
  • PHP Version: 7.2.15
  • Database Driver & Version: none

Description:

You can't run composer update and call artisan commands if add Schema::defaultStringLength calling to AppServiceProvider and you have doctrine/dbal package.

On running composer require doctrine/dbal:

In PDOConnection.php line 31:
                                             
  SQLSTATE[HY000] [2002] Connection refused  
                                             

In PDOConnection.php line 27:
                                             
  SQLSTATE[HY000] [2002] Connection refused 

On 5.8.12 works fine.

Steps To Reproduce:

  1. Create new project:
composer create-project --prefer-dist laravel/laravel blog
  1. Fix 1071 Specified key was too long error:
    Using official documentation: https://laravel.com/docs/5.8/migrations#indexes

Add Schema::defaultStringLength calling to AppServiceProvider

use Illuminate\Support\Facades\Schema;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    Schema::defaultStringLength(191);
}
  1. Try to install doctrine/dbal package:
composer require doctrine/dbal

You will get error:

In PDOConnection.php line 31:
                                             
  SQLSTATE[HY000] [2002] Connection refused  
                                             

In PDOConnection.php line 27:
                                             
  SQLSTATE[HY000] [2002] Connection refused  
                                             

Script @php artisan package:discover --ansi handling the post-autoload-dump event returned with error code 1

et-nik added a commit to et-nik/gameap that referenced this issue Apr 20, 2019

@et-nik et-nik changed the title 'SQLSTATE[HY000] [2002] Connection refused' if docktrine/dbal installed [5.8.13] 'SQLSTATE[HY000] [2002] Connection refused' if docktrine/dbal installed Apr 20, 2019

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

This is caused by #28214. /cc @JacksonIV

We should only call registerCustomDoctrineTypes() when we are actually running migrations.

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

@staudenmeir I’ll look into this. 👍🏼

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

I have tried a few things but I can't seem to reproduce this on a new laravel installation. Could you please provide me with some more information as where you encounter this error? Are you sure your database credentials and settings are correct?

Also, please make sure you are running:

composer require doctrine/dbal

instead of:

composer require docktrine/dbal

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

The error only happens when a database connection is not available.

Something like Schema::defaultStringLength(191); doesn't access the database and should work without a connection. Even if a connection is available, the builder shouldn't unnecessarily open one.

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

@staudenmeir Everything seems to work fine here, even without a connection. Maybe i'm doing something wrong though. Can you reproduce this on your Laravel installation?

Schema::defaultStringLength(); is a static method, so the constructor will not be called. Thefore the custom types won't be registered, right?

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

Yes, I can reproduce it:

  • Laravel 5.8.13
  • doctrine/dbal installed
  • Schema::defaultStringLength(191); in AppServiceProvider::boot()
  • DB_CONNECTION=mysql in .env

I can trigger the error with composer dump or php artisan serve.

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

The constructor does get called. Take a look at Illuminate\Support\Facades::getFacadeAccessor().

@TBlindaruk TBlindaruk added the bug label Apr 20, 2019

@driesvints

This comment has been minimized.

Copy link
Member

commented Apr 22, 2019

@staudenmeir I still have a hard time understanding how this can happen since the connection is first instantiated there?

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

@driesvints When the custom DBAL types get registered in the builder’s constructor it tries to find a Doctrine connection. If there’s no Doctrine connection, it will try to instantiate one. But if the database credentials or settings are incorrect it will throw a PDO exception.

If the database settings and credentials are correct, there’s no problem though. This could indeed be fixed by moving the actual registration to the migrator.

I will try to fix this as soon as i can, but unfortunately i’m a little short on time currently.

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

On the other hand, if you are calling the schema facade, you’d probably want a working database connection, right?

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

@driesvints The facade only instantiates an instance of the Connection class, but doesn't actually connect to the database. This happens in getPdo().

Is that what you mean?

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

@JacksonIV Probably, but not necessarily immediately. Only instantiating an instance of a class like MySqlBuilder (or any other class) should never open an actual database connection.

@driesvints

This comment has been minimized.

Copy link
Member

commented Apr 22, 2019

@staudenmeir I see what you mean. It's imperative that we get this fixed soon though. Otherwise it's best that we revert for now.

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

@driesvints Instead of reverting everything, i could make a PR which removes the registration of the custom DBAL types in the constructor of the MySQL builder. This way people can still call the registerCustomDBALType method manually without any problems.

@staudenmeir

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

I would revert it. Then we can take the time to fix this properly and also cover the other databases (#28214 (comment)).

@JacksonIV

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

@staudenmeir You're right, i'll start working on a proper fix as soon as possible. I'll also try to cover the other databases simultaneously!

Sorry for the hassle!

@driesvints

This comment has been minimized.

Copy link
Member

commented Apr 22, 2019

I've removed the method call in the constructor for now and this will be released tomorrow. Please send in a better solution as soon as you're able to, thanks!

#28301

@driesvints driesvints closed this Apr 22, 2019

@jasperjorna

This comment has been minimized.

Copy link

commented Apr 23, 2019

@driesvints this also breaks the package:discover command that runs after composer install. I noticed this because our build process started failing as there is no .env and no database available yet at the composer install step in our build process.

After applying your revert from #28301 it started working again.

Hopefully this can be tagged soon and properly addressed later. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.