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

Default model namespaces fail if the model is named like a Facade, e.g. Log #438

Closed
ZS-Matze opened this issue Nov 26, 2018 · 2 comments
Closed
Labels
bug An error within Lighthouse

Comments

@ZS-Matze
Copy link

ZS-Matze commented Nov 26, 2018

Describe the bug

Having an Eloquent-Model Log (in "App\Models\Log"), and querying a single object or a collection of this model, without specifying the @find- or @paginate-directive with (models: "App\\Models\\Log") results in an internal server error. Lighthouse works fine with every other Model except Log out of the box.

Expected behavior

Resolving the mentioned Model like it does with every other Model out of the box.

Schema

type Log {
    id: ID!
    context: String!
    created_at: DateTime
    updated_at: DateTime
}

type Query {
  logs: [Log!]! @paginate
  log(id: ID! @eq): Log @find
}

Output/Logs

Click to expand
{
  "errors": [
    {
      "debugMessage": "Call to undefined method Illuminate\\Log\\Writer::query()",
      "message": "Internal server error",
      "category": "internal",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "log"
      ],
      "trace": [
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/Schema/Directives/Fields/FindDirective.php",
          "line": 43,
          "call": "Illuminate\\Support\\Facades\\Facade::__callStatic('query', array(0))"
        },
        {
          "call": "Nuwave\\Lighthouse\\Schema\\Directives\\Fields\\FindDirective::Nuwave\\Lighthouse\\Schema\\Directives\\Fields\\{closure}(null, array(2), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/Schema/Factories/FieldFactory.php",
          "line": 108,
          "function": "call_user_func_array(instance of Closure, array(4))"
        },
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/Schema/Factories/FieldFactory.php",
          "line": 174,
          "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 781,
          "call": "Nuwave\\Lighthouse\\Schema\\Factories\\FieldFactory::Nuwave\\Lighthouse\\Schema\\Factories\\{closure}(null, array(1), instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 744,
          "call": "GraphQL\\Executor\\Executor::resolveOrError(instance of GraphQL\\Type\\Definition\\FieldDefinition, instance of GraphQL\\Language\\AST\\FieldNode, instance of Closure, null, instance of Nuwave\\Lighthouse\\Schema\\Context, instance of GraphQL\\Type\\Definition\\ResolveInfo)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 473,
          "call": "GraphQL\\Executor\\Executor::resolveField(GraphQLType: Query, null, instance of ArrayObject(1), array(1))"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 349,
          "call": "GraphQL\\Executor\\Executor::executeFields(GraphQLType: Query, null, array(0), instance of ArrayObject(1))"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 309,
          "call": "GraphQL\\Executor\\Executor::executeOperation(instance of GraphQL\\Language\\AST\\OperationDefinitionNode, null)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Promise/Adapter/SyncPromiseAdapter.php",
          "line": 59,
          "call": "GraphQL\\Executor\\Executor::GraphQL\\Executor\\{closure}(array(2), array(2))"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 310,
          "call": "GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter::create(instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/Executor/Executor.php",
          "line": 166,
          "call": "GraphQL\\Executor\\Executor::doExecute()"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 155,
          "call": "GraphQL\\Executor\\Executor::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, instance of GraphQL\\Language\\AST\\DocumentNode, null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null)"
        },
        {
          "file": "/srv/www/src/api/vendor/webonyx/graphql-php/src/GraphQL.php",
          "line": 86,
          "call": "GraphQL\\GraphQL::promiseToExecute(instance of GraphQL\\Executor\\Promise\\Adapter\\SyncPromiseAdapter, instance of GraphQL\\Type\\Schema, '{\n  log(id: 95) {\n    id\n    context\n  }\n}\n', null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
        },
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/GraphQL.php",
          "line": 113,
          "call": "GraphQL\\GraphQL::executeQuery(instance of GraphQL\\Type\\Schema, '{\n  log(id: 95) {\n    id\n    context\n  }\n}\n', null, instance of Nuwave\\Lighthouse\\Schema\\Context, array(0), null, null, array(29))"
        },
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/Support/Http/Controllers/GraphQLController.php",
          "line": 83,
          "call": "Nuwave\\Lighthouse\\GraphQL::executeQuery('{\n  log(id: 95) {\n    id\n    context\n  }\n}\n', instance of Nuwave\\Lighthouse\\Schema\\Context, array(0))"
        },
        {
          "file": "/srv/www/src/api/vendor/nuwave/lighthouse/src/Support/Http/Controllers/GraphQLController.php",
          "line": 62,
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController::execute(instance of Illuminate\\Http\\Request)"
        },
        {
          "call": "Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController::query(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Controller.php",
          "line": 54,
          "function": "call_user_func_array(array(2), array(1))"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php",
          "line": 45,
          "call": "Illuminate\\Routing\\Controller::callAction('query', array(1))"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
          "line": 212,
          "call": "Illuminate\\Routing\\ControllerDispatcher::dispatch(instance of Illuminate\\Routing\\Route, instance of Nuwave\\Lighthouse\\Support\\Http\\Controllers\\GraphQLController, 'query')"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Route.php",
          "line": 169,
          "call": "Illuminate\\Routing\\Route::runController()"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
          "line": 658,
          "call": "Illuminate\\Routing\\Route::run()"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
          "line": 30,
          "call": "Illuminate\\Routing\\Router::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
          "line": 102,
          "call": "Illuminate\\Routing\\Pipeline::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
          "line": 660,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
          "line": 635,
          "call": "Illuminate\\Routing\\Router::runRouteWithinStack(instance of Illuminate\\Routing\\Route, instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
          "line": 601,
          "call": "Illuminate\\Routing\\Router::runRoute(instance of Illuminate\\Http\\Request, instance of Illuminate\\Routing\\Route)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
          "line": 590,
          "call": "Illuminate\\Routing\\Router::dispatchToRoute(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
          "line": 176,
          "call": "Illuminate\\Routing\\Router::dispatch(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
          "line": 30,
          "call": "Illuminate\\Foundation\\Http\\Kernel::Illuminate\\Foundation\\Http\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/app/Http/Middleware/LogRouteMiddleware.php",
          "line": 29,
          "call": "Illuminate\\Routing\\Pipeline::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
          "line": 149,
          "call": "App\\Http\\Middleware\\LogRouteMiddleware::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
          "line": 53,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/barryvdh/laravel-cors/src/HandleCors.php",
          "line": 37,
          "call": "Illuminate\\Routing\\Pipeline::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
          "line": 149,
          "call": "Barryvdh\\Cors\\HandleCors::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
          "line": 53,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php",
          "line": 46,
          "call": "Illuminate\\Routing\\Pipeline::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
          "line": 149,
          "call": "Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode::handle(instance of Illuminate\\Http\\Request, instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php",
          "line": 53,
          "call": "Illuminate\\Pipeline\\Pipeline::Illuminate\\Pipeline\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
          "line": 102,
          "call": "Illuminate\\Routing\\Pipeline::Illuminate\\Routing\\{closure}(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
          "line": 151,
          "call": "Illuminate\\Pipeline\\Pipeline::then(instance of Closure)"
        },
        {
          "file": "/srv/www/src/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
          "line": 116,
          "call": "Illuminate\\Foundation\\Http\\Kernel::sendRequestThroughRouter(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/public/index.php",
          "line": 53,
          "call": "Illuminate\\Foundation\\Http\\Kernel::handle(instance of Illuminate\\Http\\Request)"
        },
        {
          "file": "/srv/www/src/api/server.php",
          "line": 21,
          "function": "require_once('/srv/www/src/api/public/index.php')"
        }
      ]
    }
  ],
  "data": {
    "log": null
  }
}

Environment

Lighthouse Version: 2.6.3
Laravel Version: 5.5.44 (but also with 5.7.13)
PHP Version: 7.1.24

Additional context
To solve this problem, it is necessary to add the models attribute to the directives:

@paginate(model: "App\\Models\\Log")
@find(model: "App\\Models\\Log")
@spawnia spawnia changed the title Problem to solve 'Log'-Model without using directives with 'model' attribute Default model namespaces fail if the model is named like a Facade, e.g. Log Nov 26, 2018
@spawnia
Copy link
Collaborator

spawnia commented Nov 26, 2018

This happens because Lighthouse tries to locate a class that is named after the type, so in this case Log. Only if this is not found, the default model namespace is prepended and tried again.

I can see a few solutions for this:

  1. We can check if the class exists AND is an instanceof Model. This causes an additional check during runtime, and i am not quite sure if it works for all cases.
  2. Add a hint to the docs that tell the user to use explicit namespaces for such occurences. This is probably the easiest fix but makes Lighthouse more complex to use.
  3. Blacklist the Laravel Facades so they are not used as models. This solution would not work for user defined facades, so it might not be the best.

@spawnia spawnia added the bug An error within Lighthouse label Nov 26, 2018
@spawnia
Copy link
Collaborator

spawnia commented Dec 17, 2018

Am on this, i plan to use \is_subclass_of($modelCandidate, Model::class) to check if we are dealing with the right class.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug An error within Lighthouse
Projects
None yet
Development

No branches or pull requests

2 participants