orchestral/testbench

[9.x] Breaking change due to improved error handling

Closed this issue · 4 comments

mfn commented
  • Testbench Version: v9.1.1
  • Laravel Version: v11.9.2
  • PHP Version: 8.3.7
  • Database Driver & Version: -

Description:

I'm not sure where to go with this, but I think it might be related to testbanch.

Since laravel/framework#51261 the tests at graphql-laravel are failing with L11 prefer-stable and they work with prefer-lowest.

I think this is because in the latest framework, there's a new class \Illuminate\Foundation\Exceptions\Renderer\Renderer registered in \Illuminate\Foundation\Providers\FoundationServiceProvider::registerExceptionRenderer

  $this->app->singleton(Renderer::class, function (Application $app) {
      $errorRenderer = new HtmlErrorRenderer(
          $app['config']->get('app.debug'),
      );

      return new Renderer(
          $app->make(Factory::class),
          $app->make(Listener::class),
          $errorRenderer,
          $app->make(BladeMapper::class),
          $app->basePath(),
      );
  });

That class last argument, string $basePath, can't be automagically resolved and needs to be provided.

I think due to this new changes, testbench does not know about this class and therefore does not register it and we and up with this error:

Unresolvable dependency resolving [Parameter #4 [ <required>; string $basePath ]] in class Illuminate\Foundation\Exceptions\Renderer\Renderer (500 Internal Server Error)

Stacktrace (manually converted a bit, due to mixed with HTML
 at /graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:1133
  at Illuminate\Container\Container->unresolvablePrimitive(object(ReflectionParameter))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:1042)
  at Illuminate\Container\Container->resolvePrimitive(object(ReflectionParameter))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:973)
  at Illuminate\Container\Container->resolveDependencies(array(object(ReflectionParameter), object(ReflectionParameter), object(ReflectionParameter), object(ReflectionParameter), object(ReflectionParameter)))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:935)
  at Illuminate\Container\Container->build('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer')
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:787)
  at Illuminate\Container\Container->resolve('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer', array(), true)
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:1034)
  at Illuminate\Foundation\Application->resolve('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer', array())
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Container/Container.php:723)
  at Illuminate\Container\Container->make('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer', array())
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Application.php:1019)
  at Illuminate\Foundation\Application->make('Illuminate\\Foundation\\Exceptions\\Renderer\\Renderer')
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:838)
  at Illuminate\Foundation\Exceptions\Handler->renderExceptionContent(object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:820)
  at Illuminate\Foundation\Exceptions\Handler->convertExceptionToResponse(object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:895)
  at Illuminate\Foundation\Exceptions\Handler->renderHttpException(object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:807)
  at Illuminate\Foundation\Exceptions\Handler->prepareResponse(object(Request), object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:698)
  at Illuminate\Foundation\Exceptions\Handler->renderExceptionResponse(object(Request), object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Exceptions/Handler.php:587)
  at Illuminate\Foundation\Exceptions\Handler->render(object(Request), object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/orchestra/testbench-core/src/Exceptions/Handler.php:34)
  at Orchestra\Testbench\Exceptions\Handler->render(object(Request), object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php:51)
  at Illuminate\Routing\Pipeline->handleException(object(Request), object(BadRequestGraphQLException))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:146)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:119)
  at Illuminate\Pipeline\Pipeline->then(object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php:805)
  at Illuminate\Routing\Router->runRouteWithinStack(object(Route), object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php:784)
  at Illuminate\Routing\Router->runRoute(object(Request), object(Route))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php:748)
  at Illuminate\Routing\Router->dispatchToRoute(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Routing/Router.php:737)
  at Illuminate\Routing\Router->dispatch(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:200)
  at Illuminate\Foundation\Http\Kernel->Illuminate\Foundation\Http\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:144)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21)
  at Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php:31)
  at Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21)
  at Illuminate\Foundation\Http\Middleware\TransformsRequest->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php:51)
  at Illuminate\Foundation\Http\Middleware\TrimStrings->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php:27)
  at Illuminate\Http\Middleware\ValidatePostSize->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php:110)
  at Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Http/Middleware/HandleCors.php:49)
  at Illuminate\Http\Middleware\HandleCors->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php:57)
  at Illuminate\Http\Middleware\TrustProxies->handle(object(Request), object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:183)
  at Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:119)
  at Illuminate\Pipeline\Pipeline->then(object(Closure))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:175)
  at Illuminate\Foundation\Http\Kernel->sendRequestThroughRouter(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:144)
  at Illuminate\Foundation\Http\Kernel->handle(object(Request))
     (/graphql-laravel/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:585)
  at Orchestra\Testbench\TestCase->call('POST', '/graphql', array(array(), array('query' => null), array('query' => ''), array('query' => ' '), array('query' => '#')))
     (/graphql-laravel/tests/Database/EmptyQueryTest.php:28)
  at Rebing\GraphQL\Tests\Database\EmptyQueryTest->testNoExplicitContentType()
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestCase.php:1160)
  at PHPUnit\Framework\TestCase->runTest()
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestCase.php:659)
  at PHPUnit\Framework\TestCase->runBare()
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestRunner.php:105)
  at PHPUnit\Framework\TestRunner->run(object(EmptyQueryTest))
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestCase.php:493)
  at PHPUnit\Framework\TestCase->run()
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestSuite.php:349)
  at PHPUnit\Framework\TestSuite->run()
     (/graphql-laravel/vendor/phpunit/phpunit/src/Framework/TestSuite.php:349)
  at PHPUnit\Framework\TestSuite->run()
     (/graphql-laravel/vendor/phpunit/phpunit/src/TextUI/TestRunner.php:62)
  at PHPUnit\TextUI\TestRunner->run(object(Configuration), object(DefaultResultCache), object(TestSuite))
     (/graphql-laravel/vendor/phpunit/phpunit/src/TextUI/Application.php:198)
  at PHPUnit\TextUI\Application->run(array('/graphql-laravel/vendor/phpunit/phpunit/phpunit', '--configuration', '/graphql-laravel/phpunit.xml.dist', '--filter', '/(Rebing\\\\GraphQL\\\\Tests\\\\Database\\\\EmptyQueryTest::testNoExplicitContentType)( .*)?$/', '--test-suffix', 'EmptyQueryTest.php', '/graphql-laravel/tests/Database', '--teamcity'))
     (/graphql-laravel/vendor/phpunit/phpunit/phpunit:104)

Steps To Reproduce:

  • Run the test \Rebing\GraphQL\Tests\Database\EmptyQueryTest::testNoExplicitContentType

Sorry if this is the wrong package, I tried at the Larvel project but was told they can't help me.

I think due to this new changes, testbench does not know about this class and therefore does not register it and we and up with this error:

There no reason for Testbench to know about the class when Laravel Framework will resolved it via FoundationServiceProvider. In fact we do not need to change anything to support the new error page.

mfn commented

I did quick debugging when I checked it but ... that method, which registered it in the framework, was never called in my test?

orchestral/testbench-core@e5a07ba

This tests would have failed if what you are claiming is true. You need to submit failing tests before I can debug anything.

mfn commented

orchestral/testbench-core@e5a07ba

This tests would have failed if what you are claiming is true. You need to submit failing tests before I can debug anything.

That was the missing link!

In my case, app.debug is set via \Rebing\GraphQL\Tests\TestCase::getEnvironmentSetUp.
But that is "too late", when \Illuminate\Foundation\Providers\FoundationServiceProvider::registerExceptionRenderer is called, the debug flag is not set.
However, later, when code is executed, the debug flag is set. Due to this mismatch, during bootstrap we don't register the Renderer but during execution we expect it.

I saw in your test the WithConfig attribute use for debug, applied it, and it worked -> rebing/graphql-laravel#1138

Thanks 🙏🏼