Skip to content

Commit

Permalink
NEW: Force low-level errors to throw in dev to prevent errors leaking…
Browse files Browse the repository at this point in the history
… into JSON response
  • Loading branch information
Aaron Carlino committed Jul 26, 2021
1 parent ed27d96 commit 410e405
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 4 deletions.
2 changes: 1 addition & 1 deletion _config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,4 @@ Only:
---
SilverStripe\TestSession\TestSessionEnvironment:
extensions:
- SilverStripe\GraphQL\Extensions\TestSessionEnvironmentExtension
- SilverStripe\GraphQL\Extensions\TestSessionEnvironmentExtension
1 change: 0 additions & 1 deletion _config/middlewares.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ Name: 'graphql-middlewares'
SilverStripe\Core\Injector\Injector:
# default implementation
SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface:
class: SilverStripe\GraphQL\QueryHandler\QueryHandler
properties:
Middlewares:
csrf: '%$SilverStripe\GraphQL\Middleware\CSRFMiddleware'
Expand Down
14 changes: 12 additions & 2 deletions _config/schema-default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ SilverStripe\Core\Injector\Injector:
schema: default
# use a custom handler so it's easy to override/add middlewares in the default schema
handler: '%$SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface.default'

SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface.default:
class: SilverStripe\GraphQL\QueryHandler\QueryHandler
SilverStripe\GraphQL\Schema\Schema:
schemas:
default:
Expand All @@ -35,4 +36,13 @@ SilverStripe\GraphQL\Schema\Schema:
before: paginateList
canView:
after: paginateList

---
Name: graphql-default-dev
Except:
environment: live
---
# When not in live mode, throw all errors, so the JSON response doesn't get corrupted with notice/warnings
SilverStripe\Core\Injector\Injector:
SilverStripe\GraphQL\QueryHandler\QueryHandlerInterface.default:
properties:
errorHandler: [SilverStripe\GraphQL\QueryHandler\DevErrorHandler, handleError]
30 changes: 30 additions & 0 deletions src/QueryHandler/DevErrorHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php


namespace SilverStripe\GraphQL\QueryHandler;

/**
* Throws everything, including notices, so the JSON response doesn't get corruped by E_NOTICE, E_WARN
* outputs.
*/
class DevErrorHandler
{
/**
* @param $severity
* @param $message
* @param $filename
* @param $line
* @return false
* @throws QueryException
*/
public static function handleError($severity, $message, $filename, $line)
{
if (!(error_reporting() & $severity)) {
return false;
}

$errstr = htmlspecialchars($errstr);

throw new QueryException($message);
}
}
10 changes: 10 additions & 0 deletions src/QueryHandler/QueryException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php


namespace SilverStripe\GraphQL\QueryHandler;

use Exception;

class QueryException extends Exception
{
}
19 changes: 19 additions & 0 deletions src/QueryHandler/QueryHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ class QueryHandler implements
*/
private $errorFormatter = [self::class, 'formatError'];

/**
* @var callable | null
* @config
*/
private $errorHandler = null;

/**
* @var QueryMiddleware[]
*/
Expand Down Expand Up @@ -94,6 +100,9 @@ public function query(GraphQLSchema $schema, $query, ?array $vars = []): array
*/
public function queryAndReturnResult(GraphQLSchema $schema, $query, ?array $vars = [])
{
if ($this->errorHandler) {
set_error_handler($this->errorHandler);
}
$context = $this->getContext();
$last = function ($schema, $query, $context, $vars) {
return GraphQL::executeQuery($schema, $query, null, $context, $vars);
Expand Down Expand Up @@ -174,6 +183,16 @@ public function setErrorFormatter(callable $errorFormatter): self
return $this;
}

/**
* @param callable $errorHandler
* @return QueryHandler
*/
public function setErrorHandler(callable $errorHandler): self
{
$this->errorHandler = $errorHandler;
return $this;
}

/**
* @return QueryMiddleware[]
*/
Expand Down

0 comments on commit 410e405

Please sign in to comment.