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

Error when there is no database #656

Closed
eislambey opened this issue Sep 10, 2020 · 15 comments · Fixed by #666
Closed

Error when there is no database #656

eislambey opened this issue Sep 10, 2020 · 15 comments · Fixed by #666
Labels
bug Something isn't working

Comments

@eislambey
Copy link

eislambey commented Sep 10, 2020

  • Larastan Version: 0.6.4
  • --level used: max

Description

I'm using spatie/laravel-permission package in my app. That registers some stuffs in service provider. When i setup a pipeline this error occured.

Similar issue: symfony/symfony#37069

Error Output

------ --------------------------------------------------------------------- 
  Line   Http/Controllers/Api/RoleController.php                              
 ------ --------------------------------------------------------------------- 
         Internal error: SQLSTATE[HY000] [2002] Connection refused (SQL:      
         select column_name as `column_name` from information_schema.columns  
         where table_schema = forge and table_name = roles)                   
         Run PHPStan with --debug option and post the stack trace to:         
         https://github.com/phpstan/phpstan/issues/new                        
 ------ --------------------------------------------------------------------- 
 ------ --------------------------------------------------------------------- 
  Line   Http/Resources/PermissionResource.php                                
 ------ --------------------------------------------------------------------- 
         Internal error: SQLSTATE[HY000] [2002] Connection refused (SQL:      
         select column_name as `column_name` from information_schema.columns  
         where table_schema = forge and table_name = permissions)             
         Run PHPStan with --debug option and post the stack trace to:         
         https://github.com/phpstan/phpstan/issues/new                        
 ------ --------------------------------------------------------------------- 
 ------ --------------------------------------------------------------------- 
  Line   Rules/EmptyRole.php                                                  
 ------ --------------------------------------------------------------------- 
         Internal error: SQLSTATE[HY000] [2002] Connection refused (SQL:      
         select column_name as `column_name` from information_schema.columns  
         where table_schema = forge and table_name = roles)                   
         Run PHPStan with --debug option and post the stack trace to:         
         https://github.com/phpstan/phpstan/issues/new                        
 ------ --------------------------------------------------------------------- 

Laravel code where the issue was found

class PermissionController extends Controller
{
    public function index(): JsonResponse
    {
        $permissions = Permission::all();

        return new JsonResponse([
            'data' => $permissions->pluck('name'),
        ]);
    }
}

Another example

ConnectionFactory reads Salesforce config from .env and creates a soap client.

    public function register(): void
    {
        $this->app->singleton(SforceEnterpriseClient::class, static function (): SforceEnterpriseClient {
            $factory = new ConnectionFactory();

            return $factory->createConnection();
        });
    }

Error Output

 ------ --------------------------------------------------------------------- 
  Line   Salesforce/Services/UserService.php                                  
 ------ --------------------------------------------------------------------- 
         Internal error: INVALID_LOGIN: Invalid username, password, security  
         token; or user locked out.                                           
         Run PHPStan with --debug option and post the stack trace to:         
         https://github.com/phpstan/phpstan/issues/new                        
 ------ --------------------------------------------------------------------- 
@szepeviktor
Copy link
Collaborator

This occurs when you test a package for Laravel, not an application.
Testbench boots up Laravel which is not really static analysis :)

@szepeviktor
Copy link
Collaborator

szepeviktor commented Sep 10, 2020

AFAIK Larastan used to boot up Laraval but now it does real clean static analysis. @canvural ?

@canvural
Copy link
Collaborator

Hi,

Can you run PHPStan only on one file, Http/Controllers/Api/RoleController.php for example, with --debug flag and post the stack trace here?

@szepeviktor We still boot up the Laravel.

@canvural canvural added the bug Something isn't working label Sep 10, 2020
@eislambey
Copy link
Author

Sure.

$ php vendor/bin/phpstan analyse app/Http/Controllers/Api/RoleController.php --debug 
Note: Using configuration file ./phpstan.neon.
Http/Controllers/Api/RoleController.php

   Illuminate\Database\QueryException 

  SQLSTATE[HY000] [2002] Connection refused (SQL: select column_name as `column_name` from information_schema.columns where table_schema = forge and table_name = roles)

  at vendor/laravel/framework/src/Illuminate/Database/Connection.php:671
    667|         // If an exception occurs when attempting to run a query, we'll format the error
    668|         // message to include the bindings with SQL, which will make this exception a
    669|         // lot more helpful to the developer instead of just the database's errors.
    670|         catch (Exception $e) {
  > 671|             throw new QueryException(
    672|                 $query, $this->prepareBindings($bindings), $e
    673|             );
    674|         }
    675|


@szepeviktor
Copy link
Collaborator

Maybe we need the xdebug extension to get a stack trace...

@voku
Copy link

voku commented Sep 10, 2020

Can you show your phpstan config, maybe there is some autoloader configured?

@eislambey
Copy link
Author

@voku

includes:
    - vendor/nunomaduro/larastan/extension.neon
    - vendor/timeweb/phpstan-enum/extension.neon
    - vendor/phpstan/phpstan-strict-rules/rules.neon

parameters:
    paths:
        - app

    level: max

    ignoreErrors:
        - '#Dynamic call to static method#'
        - '#Access to an undefined property SObject::#'
        - '#Variable property access on SObject#'

    checkMissingIterableValueType: false

@tsushant
Copy link

  • Larastan version: 0.6.4
  • --level: 5

I'm also using spatie/laravel-permission and got this similar error as mentioned in the issue. --debug gives the same stack trace posted in #656 (comment)

-- --------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Error                                                                                                                                                    
 -- --------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Internal error: Internal error: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known (SQL:  
     select column_name as `column_name` from information_schema.columns where table_schema = my_app and table_name = roles) in file                 
     app/Policies/RolePolicy.php                                                                                          
     Run PHPStan with --debug option and post the stack trace to:                                                                                             
     https://github.com/phpstan/phpstan/issues/new                                                                                                            
     Internal error: Internal error: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: nodename nor servname provided, or not known (SQL:  
     select column_name as `column_name` from information_schema.columns where table_schema = my_app and table_name = roles) in file                 
     app/Http/Controllers/Backend/RoleController.php                                                                      
     Run PHPStan with --debug option and post the stack trace to:                                                                                             
     https://github.com/phpstan/phpstan/issues/new                                                                                                            
 -- --------------------------------------------------------------------------------------------------------------------------------------------------------- 

@szepeviktor
Copy link
Collaborator

This may not help but we're striving to release Laravel 1.0
Currently Laravel is booted up

#656 (comment) 👀

@mfn
Copy link
Contributor

mfn commented Sep 19, 2020

Totally looking forward to Laravel 1.0 release 🥳

😏

@Daanra
Copy link
Contributor

Daanra commented Sep 25, 2020

I'm experiencing the same error. Here's a simple piece of code that will throw the error:

use Spatie\Permission\Models\Role;

public function doSomething(Role $role)
{
   return $role->permissions;
}

I did some debugging and I'm pretty sure this change is the culprit. Specifically, this part:

if (! isset(static::$guardableColumns[get_class($this)])) {
            static::$guardableColumns[get_class($this)] = $this->getConnection()
                        ->getSchemaBuilder()
                        ->getColumnListing($this->getTable());
}

Larastan seems to call the constructor for the Role class at some point, which will in turn end up performing a query here.

To temporarily fix this, one could use a Laravel version before this change was added. E.g. 7.23.2 (Note that this was a security fix so using a version of Laravel that does not have this change can be a bit dangerous)

@canvural
Copy link
Collaborator

canvural commented Sep 25, 2020

In work projects, we are extending the \Spatie\Permission\Models\Role model and using our own Role model. So at first, I did not see this error.

But when I explicitly use that model like so:

public function doSomething(\Spatie\Permission\Models\Role $role): Collection
{
    return $role->permissions;
}

it produces the same error as in the original issue.

The error originates from here. The solution I'm thinking is wrapping this statement in try/catch block. And fallback to "guessing" the table name in catch block. Like this:

--- src/Properties/ModelPropertyExtension.php
+++ src/Properties/ModelPropertyExtension.php
@@ -73,9 +73,16 @@
         }
 
         $modelName = $classReflection->getNativeReflection()->getName();
+
         /** @var Model $modelInstance */
-        $modelInstance = new $modelName;
-        $tableName = $modelInstance->getTable();
+        try {
+            $modelInstance = new $modelName;
+
+            $tableName = $modelInstance->getTable();
+        } catch (\Exception $e) {
+            $tableName =  Str::snake(Str::pluralStudly(class_basename($modelName)));
+        }
+
 
         if (! array_key_exists($tableName, $this->tables)) {
             return false;

Or we can just return false from the catch block. Ignoring this model.

Any other suggestions?

@Daanra
Copy link
Contributor

Daanra commented Sep 25, 2020

@canvural

Seems good to me. Can't think of another solution.

@canvural
Copy link
Collaborator

@eislambey and @Daanra Can you test master and check if it fixed the issue for you?

@Daanra
Copy link
Contributor

Daanra commented Sep 25, 2020

@canvural That fixed it for me. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants