Skip to content

Commit

Permalink
FIX Attempt to rebuild the schema if a schema file is missing
Browse files Browse the repository at this point in the history
  • Loading branch information
emteknetnz committed Mar 9, 2023
1 parent 81755df commit c2c9b1a
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
29 changes: 28 additions & 1 deletion src/Schema/Storage/AbstractTypeRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
use GraphQL\Type\Definition\ListOfType;
use Exception;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\GraphQL\Schema\SchemaBuilder;
use SilverStripe\GraphQL\Schema\Exception\EmptySchemaException;
use SilverStripe\Control\Controller;
use SilverStripe\GraphQL\Controller as GraphQLController;

abstract class AbstractTypeRegistry
{
Expand All @@ -21,7 +25,30 @@ abstract class AbstractTypeRegistry
*/
public static function get(string $typename)
{
return static::fromCache($typename);
try {
return static::fromCache($typename);
} catch (Exception $e) {
if (!Controller::has_curr() ||
!(Controller::curr() instanceof GraphQLController) ||
!Controller::curr()->autobuildEnabled()
) {
throw $e;
}
// Try to rebuild the whole schema as fallback.
// This is to solve mysterious edge cases where schema files do not exist when they should.
// These edge cases are more likely on multi-server environments
$dirParts = explode(DIRECTORY_SEPARATOR, static::getSourceDirectory());
$key = $dirParts[count($dirParts) - 1];
$builder = SchemaBuilder::singleton();
$schema = $builder->boot($key);
try {
$builder->build($schema, true);
} catch (EmptySchemaException $e) {
// noop
}
// Attempt to return again now the schema has been rebuilt.
return static::fromCache($typename);
}
}

abstract protected static function getSourceDirectory(): string;
Expand Down
6 changes: 6 additions & 0 deletions tests/Schema/IntegrationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1215,6 +1215,12 @@ private function createSchema(TestSchemaBuilder $factory): Schema

$factory->build($schema, true);

// Register as the default SchemaBuilder so that any calls to
// SchemaBuidler::singleton() get this TestSchemaBuilder
// This is important for the call in AbstractTypeRegisty::get() because
// otherwise a duplicate .graphql-generated folder will be created
Injector::inst()->registerService($factory, SchemaBuilder::class);

return $schema;
}

Expand Down

0 comments on commit c2c9b1a

Please sign in to comment.