mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-29 16:36:02 +03:00
commit
5a90e9bd64
3
.gitignore
vendored
3
.gitignore
vendored
@ -1,5 +1,4 @@
|
|||||||
.idea/
|
|
||||||
composer.phar
|
composer.phar
|
||||||
composer.lock
|
composer.lock
|
||||||
|
phpcs.xml
|
||||||
vendor/
|
vendor/
|
||||||
bin/
|
|
||||||
|
20
.travis.yml
20
.travis.yml
@ -2,8 +2,6 @@ dist: trusty
|
|||||||
language: php
|
language: php
|
||||||
|
|
||||||
php:
|
php:
|
||||||
- 5.6
|
|
||||||
- 7.0
|
|
||||||
- 7.1
|
- 7.1
|
||||||
- 7.2
|
- 7.2
|
||||||
- nightly
|
- nightly
|
||||||
@ -47,3 +45,21 @@ jobs:
|
|||||||
after_script:
|
after_script:
|
||||||
- wget https://scrutinizer-ci.com/ocular.phar
|
- wget https://scrutinizer-ci.com/ocular.phar
|
||||||
- php ocular.phar code-coverage:upload --format=php-clover clover.xml
|
- php ocular.phar code-coverage:upload --format=php-clover clover.xml
|
||||||
|
- stage: Pull request coding standard
|
||||||
|
if: type = pull_request
|
||||||
|
install: travis_retry composer install --prefer-dist
|
||||||
|
script:
|
||||||
|
- |
|
||||||
|
if [ $TRAVIS_BRANCH != "master" ]; then
|
||||||
|
git remote set-branches --add origin $TRAVIS_BRANCH;
|
||||||
|
git fetch origin $TRAVIS_BRANCH;
|
||||||
|
fi
|
||||||
|
- git merge-base origin/$TRAVIS_BRANCH $TRAVIS_PULL_REQUEST_SHA || git fetch origin +refs/pull/$TRAVIS_PULL_REQUEST/merge --unshallow
|
||||||
|
- wget https://github.com/diff-sniffer/git/releases/download/0.1.0/git-phpcs.phar
|
||||||
|
- php git-phpcs.phar origin/$TRAVIS_BRANCH...$TRAVIS_PULL_REQUEST_SHA
|
||||||
|
- stage: Coding standard
|
||||||
|
if: NOT type = pull_request
|
||||||
|
php: 7.1
|
||||||
|
install: travis_retry composer install --prefer-dist
|
||||||
|
script:
|
||||||
|
- ./vendor/bin/phpcs
|
||||||
|
@ -9,10 +9,11 @@
|
|||||||
"API"
|
"API"
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=5.6",
|
"php": "^7.1",
|
||||||
"ext-mbstring": "*"
|
"ext-mbstring": "*"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"doctrine/coding-standard": "^4.0",
|
||||||
"phpunit/phpunit": "^4.8",
|
"phpunit/phpunit": "^4.8",
|
||||||
"psr/http-message": "^1.0"
|
"psr/http-message": "^1.0"
|
||||||
},
|
},
|
||||||
@ -35,5 +36,8 @@
|
|||||||
"suggest": {
|
"suggest": {
|
||||||
"react/promise": "To leverage async resolving on React PHP platform",
|
"react/promise": "To leverage async resolving on React PHP platform",
|
||||||
"psr/http-message": "To use standard GraphQL server"
|
"psr/http-message": "To use standard GraphQL server"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint" : "vendor/bin/phpcs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
93
phpcs.xml.dist
Normal file
93
phpcs.xml.dist
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<ruleset>
|
||||||
|
<arg name="basepath" value="." />
|
||||||
|
<arg name="extensions" value="php" />
|
||||||
|
<arg name="parallel" value="80" />
|
||||||
|
<arg name="cache" value=".phpcs-cache" />
|
||||||
|
<arg name="colors" />
|
||||||
|
|
||||||
|
<!-- Ignore warnings, show progress of the run and show sniff names -->
|
||||||
|
<arg value="nps" />
|
||||||
|
|
||||||
|
<file>src</file>
|
||||||
|
<file>tests</file>
|
||||||
|
|
||||||
|
<rule ref="Doctrine">
|
||||||
|
<!--Disable PHP7+ features that might cause BC breaks for now -->
|
||||||
|
<exclude name="SlevomatCodingStandard.Classes.ClassConstantVisibility.MissingConstantVisibility" />
|
||||||
|
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingParameterTypeHint" />
|
||||||
|
<exclude name="SlevomatCodingStandard.TypeHints.TypeHintDeclaration.MissingReturnTypeHint" />
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<!--@api annotation is required for now -->
|
||||||
|
<rule ref="SlevomatCodingStandard.TypeHints.TypeHintDeclaration">
|
||||||
|
<properties>
|
||||||
|
<property
|
||||||
|
name="usefulAnnotations"
|
||||||
|
type="array"
|
||||||
|
value="
|
||||||
|
@after,
|
||||||
|
@afterClass,
|
||||||
|
@AfterMethods,
|
||||||
|
@api,
|
||||||
|
@Attribute,
|
||||||
|
@Attributes,
|
||||||
|
@before,
|
||||||
|
@beforeClass,
|
||||||
|
@BeforeMethods,
|
||||||
|
@covers,
|
||||||
|
@coversDefaultClass,
|
||||||
|
@coversNothing,
|
||||||
|
@dataProvider,
|
||||||
|
@depends,
|
||||||
|
@deprecated,
|
||||||
|
@doesNotPerformAssertions,
|
||||||
|
@Enum,
|
||||||
|
@expectedDeprecation,
|
||||||
|
@expectedException,
|
||||||
|
@expectedExceptionCode,
|
||||||
|
@expectedExceptionMessage,
|
||||||
|
@expectedExceptionMessageRegExp,
|
||||||
|
@group,
|
||||||
|
@Groups,
|
||||||
|
@IgnoreAnnotation,
|
||||||
|
@internal,
|
||||||
|
@Iterations,
|
||||||
|
@link,
|
||||||
|
@ODM\,
|
||||||
|
@ORM\,
|
||||||
|
@requires,
|
||||||
|
@Required,
|
||||||
|
@Revs,
|
||||||
|
@runInSeparateProcess,
|
||||||
|
@runTestsInSeparateProcesses,
|
||||||
|
@see,
|
||||||
|
@Target,
|
||||||
|
@test,
|
||||||
|
@throws,
|
||||||
|
@uses
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
|
||||||
|
<rule ref="SlevomatCodingStandard.Commenting.ForbiddenAnnotations">
|
||||||
|
<properties>
|
||||||
|
<property
|
||||||
|
name="forbiddenAnnotations"
|
||||||
|
type="array"
|
||||||
|
value="
|
||||||
|
@author,
|
||||||
|
@category,
|
||||||
|
@copyright,
|
||||||
|
@created,
|
||||||
|
@license,
|
||||||
|
@package,
|
||||||
|
@since,
|
||||||
|
@subpackage,
|
||||||
|
@version
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</properties>
|
||||||
|
</rule>
|
||||||
|
</ruleset>
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -6,7 +9,7 @@ namespace GraphQL\Error;
|
|||||||
*/
|
*/
|
||||||
class Debug
|
class Debug
|
||||||
{
|
{
|
||||||
const INCLUDE_DEBUG_MESSAGE = 1;
|
const INCLUDE_DEBUG_MESSAGE = 1;
|
||||||
const INCLUDE_TRACE = 2;
|
const INCLUDE_TRACE = 2;
|
||||||
const RETHROW_INTERNAL_EXCEPTIONS = 4;
|
const RETHROW_INTERNAL_EXCEPTIONS = 4;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,18 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
use GraphQL\Language\Source;
|
use GraphQL\Language\Source;
|
||||||
use GraphQL\Language\SourceLocation;
|
use GraphQL\Language\SourceLocation;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use function array_filter;
|
||||||
|
use function array_map;
|
||||||
|
use function array_merge;
|
||||||
|
use function is_array;
|
||||||
|
use function iterator_to_array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Describes an Error found during the parse, validate, or
|
* Describes an Error found during the parse, validate, or
|
||||||
@ -22,7 +30,7 @@ use GraphQL\Utils\Utils;
|
|||||||
*/
|
*/
|
||||||
class Error extends \Exception implements \JsonSerializable, ClientAware
|
class Error extends \Exception implements \JsonSerializable, ClientAware
|
||||||
{
|
{
|
||||||
const CATEGORY_GRAPHQL = 'graphql';
|
const CATEGORY_GRAPHQL = 'graphql';
|
||||||
const CATEGORY_INTERNAL = 'internal';
|
const CATEGORY_INTERNAL = 'internal';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -32,23 +40,21 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
*/
|
*/
|
||||||
public $message;
|
public $message;
|
||||||
|
|
||||||
/**
|
/** @var SourceLocation[] */
|
||||||
* @var SourceLocation[]
|
|
||||||
*/
|
|
||||||
private $locations;
|
private $locations;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array describing the JSON-path into the execution response which
|
* An array describing the JSON-path into the execution response which
|
||||||
* corresponds to this error. Only included for errors during execution.
|
* corresponds to this error. Only included for errors during execution.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var mixed[]|null
|
||||||
*/
|
*/
|
||||||
public $path;
|
public $path;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array of GraphQL AST Nodes corresponding to this error.
|
* An array of GraphQL AST Nodes corresponding to this error.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var Node[]|null
|
||||||
*/
|
*/
|
||||||
public $nodes;
|
public $nodes;
|
||||||
|
|
||||||
@ -62,34 +68,74 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
*/
|
*/
|
||||||
private $source;
|
private $source;
|
||||||
|
|
||||||
/**
|
/** @var int[]|null */
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $positions;
|
private $positions;
|
||||||
|
|
||||||
/**
|
/** @var bool */
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
private $isClientSafe;
|
private $isClientSafe;
|
||||||
|
|
||||||
/**
|
/** @var string */
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $category;
|
protected $category;
|
||||||
|
|
||||||
/**
|
/** @var mixed[]|null */
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
protected $extensions;
|
protected $extensions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $message
|
||||||
|
* @param Node[]|null $nodes
|
||||||
|
* @param mixed[]|null $positions
|
||||||
|
* @param mixed[]|null $path
|
||||||
|
* @param \Throwable $previous
|
||||||
|
* @param mixed[] $extensions
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
$message,
|
||||||
|
$nodes = null,
|
||||||
|
?Source $source = null,
|
||||||
|
$positions = null,
|
||||||
|
$path = null,
|
||||||
|
$previous = null,
|
||||||
|
array $extensions = []
|
||||||
|
) {
|
||||||
|
parent::__construct($message, 0, $previous);
|
||||||
|
|
||||||
|
// Compute list of blame nodes.
|
||||||
|
if ($nodes instanceof \Traversable) {
|
||||||
|
$nodes = iterator_to_array($nodes);
|
||||||
|
} elseif ($nodes && ! is_array($nodes)) {
|
||||||
|
$nodes = [$nodes];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->nodes = $nodes;
|
||||||
|
$this->source = $source;
|
||||||
|
$this->positions = $positions;
|
||||||
|
$this->path = $path;
|
||||||
|
$this->extensions = $extensions ?: (
|
||||||
|
$previous && $previous instanceof self
|
||||||
|
? $previous->extensions
|
||||||
|
: []
|
||||||
|
);
|
||||||
|
|
||||||
|
if ($previous instanceof ClientAware) {
|
||||||
|
$this->isClientSafe = $previous->isClientSafe();
|
||||||
|
$this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
|
||||||
|
} elseif ($previous) {
|
||||||
|
$this->isClientSafe = false;
|
||||||
|
$this->category = static::CATEGORY_INTERNAL;
|
||||||
|
} else {
|
||||||
|
$this->isClientSafe = true;
|
||||||
|
$this->category = static::CATEGORY_GRAPHQL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given an arbitrary Error, presumably thrown while attempting to execute a
|
* Given an arbitrary Error, presumably thrown while attempting to execute a
|
||||||
* GraphQL operation, produce a new GraphQLError aware of the location in the
|
* GraphQL operation, produce a new GraphQLError aware of the location in the
|
||||||
* document responsible for the original Error.
|
* document responsible for the original Error.
|
||||||
*
|
*
|
||||||
* @param $error
|
* @param mixed $error
|
||||||
* @param array|null $nodes
|
* @param Node[]|null $nodes
|
||||||
* @param array|null $path
|
* @param mixed[]|null $path
|
||||||
* @return Error
|
* @return Error
|
||||||
*/
|
*/
|
||||||
public static function createLocatedError($error, $nodes = null, $path = null)
|
public static function createLocatedError($error, $nodes = null, $path = null)
|
||||||
@ -99,22 +145,22 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
return $error;
|
return $error;
|
||||||
} else {
|
} else {
|
||||||
$nodes = $nodes ?: $error->nodes;
|
$nodes = $nodes ?: $error->nodes;
|
||||||
$path = $path ?: $error->path;
|
$path = $path ?: $error->path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$source = $positions = $originalError = null;
|
$source = $positions = $originalError = null;
|
||||||
$extensions = [];
|
$extensions = [];
|
||||||
|
|
||||||
if ($error instanceof self) {
|
if ($error instanceof self) {
|
||||||
$message = $error->getMessage();
|
$message = $error->getMessage();
|
||||||
$originalError = $error;
|
$originalError = $error;
|
||||||
$nodes = $error->nodes ?: $nodes;
|
$nodes = $error->nodes ?: $nodes;
|
||||||
$source = $error->source;
|
$source = $error->source;
|
||||||
$positions = $error->positions;
|
$positions = $error->positions;
|
||||||
$extensions = $error->extensions;
|
$extensions = $error->extensions;
|
||||||
} else if ($error instanceof \Exception || $error instanceof \Throwable) {
|
} elseif ($error instanceof \Exception || $error instanceof \Throwable) {
|
||||||
$message = $error->getMessage();
|
$message = $error->getMessage();
|
||||||
$originalError = $error;
|
$originalError = $error;
|
||||||
} else {
|
} else {
|
||||||
$message = (string) $error;
|
$message = (string) $error;
|
||||||
@ -131,66 +177,14 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Error $error
|
* @return mixed[]
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public static function formatError(Error $error)
|
public static function formatError(Error $error)
|
||||||
{
|
{
|
||||||
return $error->toSerializableArray();
|
return $error->toSerializableArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $message
|
|
||||||
* @param array|Node|null $nodes
|
|
||||||
* @param Source $source
|
|
||||||
* @param array|null $positions
|
|
||||||
* @param array|null $path
|
|
||||||
* @param \Throwable $previous
|
|
||||||
* @param array $extensions
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
$message,
|
|
||||||
$nodes = null,
|
|
||||||
Source $source = null,
|
|
||||||
$positions = null,
|
|
||||||
$path = null,
|
|
||||||
$previous = null,
|
|
||||||
array $extensions = []
|
|
||||||
)
|
|
||||||
{
|
|
||||||
parent::__construct($message, 0, $previous);
|
|
||||||
|
|
||||||
// Compute list of blame nodes.
|
|
||||||
if ($nodes instanceof \Traversable) {
|
|
||||||
$nodes = iterator_to_array($nodes);
|
|
||||||
} else if ($nodes && !is_array($nodes)) {
|
|
||||||
$nodes = [$nodes];
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->nodes = $nodes;
|
|
||||||
$this->source = $source;
|
|
||||||
$this->positions = $positions;
|
|
||||||
$this->path = $path;
|
|
||||||
$this->extensions = $extensions ?: (
|
|
||||||
$previous && $previous instanceof self
|
|
||||||
? $previous->extensions
|
|
||||||
: []
|
|
||||||
);
|
|
||||||
|
|
||||||
if ($previous instanceof ClientAware) {
|
|
||||||
$this->isClientSafe = $previous->isClientSafe();
|
|
||||||
$this->category = $previous->getCategory() ?: static::CATEGORY_INTERNAL;
|
|
||||||
} else if ($previous) {
|
|
||||||
$this->isClientSafe = false;
|
|
||||||
$this->category = static::CATEGORY_INTERNAL;
|
|
||||||
} else {
|
|
||||||
$this->isClientSafe = true;
|
|
||||||
$this->category = static::CATEGORY_GRAPHQL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @inheritdoc
|
* @inheritdoc
|
||||||
*/
|
*/
|
||||||
@ -212,29 +206,36 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
*/
|
*/
|
||||||
public function getSource()
|
public function getSource()
|
||||||
{
|
{
|
||||||
if (null === $this->source) {
|
if ($this->source === null) {
|
||||||
if (!empty($this->nodes[0]) && !empty($this->nodes[0]->loc)) {
|
if (! empty($this->nodes[0]) && ! empty($this->nodes[0]->loc)) {
|
||||||
$this->source = $this->nodes[0]->loc->source;
|
$this->source = $this->nodes[0]->loc->source;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->source;
|
return $this->source;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return int[]
|
||||||
*/
|
*/
|
||||||
public function getPositions()
|
public function getPositions()
|
||||||
{
|
{
|
||||||
if (null === $this->positions) {
|
if ($this->positions === null && ! empty($this->nodes)) {
|
||||||
if (!empty($this->nodes)) {
|
$positions = array_map(
|
||||||
$positions = array_map(function($node) {
|
function ($node) {
|
||||||
return isset($node->loc) ? $node->loc->start : null;
|
return isset($node->loc) ? $node->loc->start : null;
|
||||||
}, $this->nodes);
|
},
|
||||||
$this->positions = array_filter($positions, function($p) {
|
$this->nodes
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->positions = array_filter(
|
||||||
|
$positions,
|
||||||
|
function ($p) {
|
||||||
return $p !== null;
|
return $p !== null;
|
||||||
});
|
}
|
||||||
}
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->positions;
|
return $this->positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,21 +255,29 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
*/
|
*/
|
||||||
public function getLocations()
|
public function getLocations()
|
||||||
{
|
{
|
||||||
if (null === $this->locations) {
|
if ($this->locations === null) {
|
||||||
$positions = $this->getPositions();
|
$positions = $this->getPositions();
|
||||||
$source = $this->getSource();
|
$source = $this->getSource();
|
||||||
$nodes = $this->nodes;
|
$nodes = $this->nodes;
|
||||||
|
|
||||||
if ($positions && $source) {
|
if ($positions && $source) {
|
||||||
$this->locations = array_map(function ($pos) use ($source) {
|
$this->locations = array_map(
|
||||||
return $source->getLocation($pos);
|
function ($pos) use ($source) {
|
||||||
}, $positions);
|
return $source->getLocation($pos);
|
||||||
} else if ($nodes) {
|
},
|
||||||
$this->locations = array_filter(array_map(function ($node) {
|
$positions
|
||||||
if ($node->loc) {
|
);
|
||||||
return $node->loc->source->getLocation($node->loc->start);
|
} elseif ($nodes) {
|
||||||
}
|
$this->locations = array_filter(
|
||||||
}, $nodes));
|
array_map(
|
||||||
|
function ($node) {
|
||||||
|
if ($node->loc) {
|
||||||
|
return $node->loc->source->getLocation($node->loc->start);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
$nodes
|
||||||
|
)
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
$this->locations = [];
|
$this->locations = [];
|
||||||
}
|
}
|
||||||
@ -278,7 +287,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array|Node[]|null
|
* @return Node[]|null
|
||||||
*/
|
*/
|
||||||
public function getNodes()
|
public function getNodes()
|
||||||
{
|
{
|
||||||
@ -290,7 +299,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* Only included for execution errors.
|
* Only included for execution errors.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @return array|null
|
* @return mixed[]|null
|
||||||
*/
|
*/
|
||||||
public function getPath()
|
public function getPath()
|
||||||
{
|
{
|
||||||
@ -298,7 +307,7 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public function getExtensions()
|
public function getExtensions()
|
||||||
{
|
{
|
||||||
@ -309,26 +318,29 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* Returns array representation of error suitable for serialization
|
* Returns array representation of error suitable for serialization
|
||||||
*
|
*
|
||||||
* @deprecated Use FormattedError::createFromException() instead
|
* @deprecated Use FormattedError::createFromException() instead
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public function toSerializableArray()
|
public function toSerializableArray()
|
||||||
{
|
{
|
||||||
$arr = [
|
$arr = [
|
||||||
'message' => $this->getMessage()
|
'message' => $this->getMessage(),
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($this->getExtensions()) {
|
if ($this->getExtensions()) {
|
||||||
$arr = array_merge($this->getExtensions(), $arr);
|
$arr = array_merge($this->getExtensions(), $arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
$locations = Utils::map($this->getLocations(), function(SourceLocation $loc) {
|
$locations = Utils::map(
|
||||||
return $loc->toSerializableArray();
|
$this->getLocations(),
|
||||||
});
|
function (SourceLocation $loc) {
|
||||||
|
return $loc->toSerializableArray();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!empty($locations)) {
|
if (! empty($locations)) {
|
||||||
$arr['locations'] = $locations;
|
$arr['locations'] = $locations;
|
||||||
}
|
}
|
||||||
if (!empty($this->path)) {
|
if (! empty($this->path)) {
|
||||||
$arr['path'] = $this->path;
|
$arr['path'] = $this->path;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -340,9 +352,8 @@ class Error extends \Exception implements \JsonSerializable, ClientAware
|
|||||||
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
* @link http://php.net/manual/en/jsonserializable.jsonserialize.php
|
||||||
* @return mixed data which can be serialized by <b>json_encode</b>,
|
* @return mixed data which can be serialized by <b>json_encode</b>,
|
||||||
* which is a value of any type other than a resource.
|
* which is a value of any type other than a resource.
|
||||||
* @since 5.4.0
|
|
||||||
*/
|
*/
|
||||||
function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return $this->toSerializableArray();
|
return $this->toSerializableArray();
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
use GraphQL\Language\AST\Node;
|
use GraphQL\Language\AST\Node;
|
||||||
@ -7,6 +10,26 @@ use GraphQL\Language\SourceLocation;
|
|||||||
use GraphQL\Type\Definition\Type;
|
use GraphQL\Type\Definition\Type;
|
||||||
use GraphQL\Type\Definition\WrappingType;
|
use GraphQL\Type\Definition\WrappingType;
|
||||||
use GraphQL\Utils\Utils;
|
use GraphQL\Utils\Utils;
|
||||||
|
use function addcslashes;
|
||||||
|
use function array_filter;
|
||||||
|
use function array_intersect_key;
|
||||||
|
use function array_map;
|
||||||
|
use function array_merge;
|
||||||
|
use function array_shift;
|
||||||
|
use function count;
|
||||||
|
use function get_class;
|
||||||
|
use function gettype;
|
||||||
|
use function implode;
|
||||||
|
use function is_array;
|
||||||
|
use function is_bool;
|
||||||
|
use function is_object;
|
||||||
|
use function is_scalar;
|
||||||
|
use function is_string;
|
||||||
|
use function mb_strlen;
|
||||||
|
use function preg_split;
|
||||||
|
use function sprintf;
|
||||||
|
use function str_repeat;
|
||||||
|
use function strlen;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class is used for [default error formatting](error-handling.md).
|
* This class is used for [default error formatting](error-handling.md).
|
||||||
@ -15,6 +38,7 @@ use GraphQL\Utils\Utils;
|
|||||||
*/
|
*/
|
||||||
class FormattedError
|
class FormattedError
|
||||||
{
|
{
|
||||||
|
/** @var string */
|
||||||
private static $internalErrorMessage = 'Internal server error';
|
private static $internalErrorMessage = 'Internal server error';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,7 +57,6 @@ class FormattedError
|
|||||||
* Prints a GraphQLError to a string, representing useful location information
|
* Prints a GraphQLError to a string, representing useful location information
|
||||||
* about the error's position in the source.
|
* about the error's position in the source.
|
||||||
*
|
*
|
||||||
* @param Error $error
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printError(Error $error)
|
public static function printError(Error $error)
|
||||||
@ -41,63 +64,65 @@ class FormattedError
|
|||||||
$printedLocations = [];
|
$printedLocations = [];
|
||||||
if ($error->nodes) {
|
if ($error->nodes) {
|
||||||
/** @var Node $node */
|
/** @var Node $node */
|
||||||
foreach($error->nodes as $node) {
|
foreach ($error->nodes as $node) {
|
||||||
if ($node->loc) {
|
if (! $node->loc) {
|
||||||
$printedLocations[] = self::highlightSourceAtLocation(
|
continue;
|
||||||
$node->loc->source,
|
|
||||||
$node->loc->source->getLocation($node->loc->start)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($node->loc->source === null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$printedLocations[] = self::highlightSourceAtLocation(
|
||||||
|
$node->loc->source,
|
||||||
|
$node->loc->source->getLocation($node->loc->start)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} else if ($error->getSource() && $error->getLocations()) {
|
} elseif ($error->getSource() && $error->getLocations()) {
|
||||||
$source = $error->getSource();
|
$source = $error->getSource();
|
||||||
foreach($error->getLocations() as $location) {
|
foreach ($error->getLocations() as $location) {
|
||||||
$printedLocations[] = self::highlightSourceAtLocation($source, $location);
|
$printedLocations[] = self::highlightSourceAtLocation($source, $location);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return !$printedLocations
|
return ! $printedLocations
|
||||||
? $error->getMessage()
|
? $error->getMessage()
|
||||||
: join("\n\n", array_merge([$error->getMessage()], $printedLocations)) . "\n";
|
: implode("\n\n", array_merge([$error->getMessage()], $printedLocations)) . "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render a helpful description of the location of the error in the GraphQL
|
* Render a helpful description of the location of the error in the GraphQL
|
||||||
* Source document.
|
* Source document.
|
||||||
*
|
*
|
||||||
* @param Source $source
|
|
||||||
* @param SourceLocation $location
|
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function highlightSourceAtLocation(Source $source, SourceLocation $location)
|
private static function highlightSourceAtLocation(Source $source, SourceLocation $location)
|
||||||
{
|
{
|
||||||
$line = $location->line;
|
$line = $location->line;
|
||||||
$lineOffset = $source->locationOffset->line - 1;
|
$lineOffset = $source->locationOffset->line - 1;
|
||||||
$columnOffset = self::getColumnOffset($source, $location);
|
$columnOffset = self::getColumnOffset($source, $location);
|
||||||
$contextLine = $line + $lineOffset;
|
$contextLine = $line + $lineOffset;
|
||||||
$contextColumn = $location->column + $columnOffset;
|
$contextColumn = $location->column + $columnOffset;
|
||||||
$prevLineNum = (string) ($contextLine - 1);
|
$prevLineNum = (string) ($contextLine - 1);
|
||||||
$lineNum = (string) $contextLine;
|
$lineNum = (string) $contextLine;
|
||||||
$nextLineNum = (string) ($contextLine + 1);
|
$nextLineNum = (string) ($contextLine + 1);
|
||||||
$padLen = strlen($nextLineNum);
|
$padLen = strlen($nextLineNum);
|
||||||
$lines = preg_split('/\r\n|[\n\r]/', $source->body);
|
$lines = preg_split('/\r\n|[\n\r]/', $source->body);
|
||||||
|
|
||||||
$lines[0] = self::whitespace($source->locationOffset->column - 1) . $lines[0];
|
$lines[0] = self::whitespace($source->locationOffset->column - 1) . $lines[0];
|
||||||
|
|
||||||
$outputLines = [
|
$outputLines = [
|
||||||
"{$source->name} ($contextLine:$contextColumn)",
|
sprintf('%s (%s:%s)', $source->name, $contextLine, $contextColumn),
|
||||||
$line >= 2 ? (self::lpad($padLen, $prevLineNum) . ': ' . $lines[$line - 2]) : null,
|
$line >= 2 ? (self::lpad($padLen, $prevLineNum) . ': ' . $lines[$line - 2]) : null,
|
||||||
self::lpad($padLen, $lineNum) . ': ' . $lines[$line - 1],
|
self::lpad($padLen, $lineNum) . ': ' . $lines[$line - 1],
|
||||||
self::whitespace(2 + $padLen + $contextColumn - 1) . '^',
|
self::whitespace(2 + $padLen + $contextColumn - 1) . '^',
|
||||||
$line < count($lines)? self::lpad($padLen, $nextLineNum) . ': ' . $lines[$line] : null
|
$line < count($lines) ? self::lpad($padLen, $nextLineNum) . ': ' . $lines[$line] : null,
|
||||||
];
|
];
|
||||||
|
|
||||||
return join("\n", array_filter($outputLines));
|
return implode("\n", array_filter($outputLines));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Source $source
|
|
||||||
* @param SourceLocation $location
|
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
private static function getColumnOffset(Source $source, SourceLocation $location)
|
private static function getColumnOffset(Source $source, SourceLocation $location)
|
||||||
@ -109,7 +134,8 @@ class FormattedError
|
|||||||
* @param int $len
|
* @param int $len
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function whitespace($len) {
|
private static function whitespace($len)
|
||||||
|
{
|
||||||
return str_repeat(' ', $len);
|
return str_repeat(' ', $len);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +143,8 @@ class FormattedError
|
|||||||
* @param int $len
|
* @param int $len
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private static function lpad($len, $str) {
|
private static function lpad($len, $str)
|
||||||
|
{
|
||||||
return self::whitespace($len - mb_strlen($str)) . $str;
|
return self::whitespace($len - mb_strlen($str)) . $str;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,16 +159,16 @@ class FormattedError
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @param \Throwable $e
|
* @param \Throwable $e
|
||||||
* @param bool|int $debug
|
* @param bool|int $debug
|
||||||
* @param string $internalErrorMessage
|
* @param string $internalErrorMessage
|
||||||
* @return array
|
* @return mixed[]
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public static function createFromException($e, $debug = false, $internalErrorMessage = null)
|
public static function createFromException($e, $debug = false, $internalErrorMessage = null)
|
||||||
{
|
{
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
$e instanceof \Exception || $e instanceof \Throwable,
|
$e instanceof \Exception || $e instanceof \Throwable,
|
||||||
"Expected exception, got %s",
|
'Expected exception, got %s',
|
||||||
Utils::getVariableType($e)
|
Utils::getVariableType($e)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -149,13 +176,13 @@ class FormattedError
|
|||||||
|
|
||||||
if ($e instanceof ClientAware) {
|
if ($e instanceof ClientAware) {
|
||||||
$formattedError = [
|
$formattedError = [
|
||||||
'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
|
'message' => $e->isClientSafe() ? $e->getMessage() : $internalErrorMessage,
|
||||||
'category' => $e->getCategory()
|
'category' => $e->getCategory(),
|
||||||
];
|
];
|
||||||
} else {
|
} else {
|
||||||
$formattedError = [
|
$formattedError = [
|
||||||
'message' => $internalErrorMessage,
|
'message' => $internalErrorMessage,
|
||||||
'category' => Error::CATEGORY_INTERNAL
|
'category' => Error::CATEGORY_INTERNAL,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -164,14 +191,17 @@ class FormattedError
|
|||||||
$formattedError = array_merge($e->getExtensions(), $formattedError);
|
$formattedError = array_merge($e->getExtensions(), $formattedError);
|
||||||
}
|
}
|
||||||
|
|
||||||
$locations = Utils::map($e->getLocations(), function(SourceLocation $loc) {
|
$locations = Utils::map(
|
||||||
return $loc->toSerializableArray();
|
$e->getLocations(),
|
||||||
});
|
function (SourceLocation $loc) {
|
||||||
|
return $loc->toSerializableArray();
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
if (!empty($locations)) {
|
if (! empty($locations)) {
|
||||||
$formattedError['locations'] = $locations;
|
$formattedError['locations'] = $locations;
|
||||||
}
|
}
|
||||||
if (!empty($e->path)) {
|
if (! empty($e->path)) {
|
||||||
$formattedError['path'] = $e->path;
|
$formattedError['path'] = $e->path;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -187,35 +217,37 @@ class FormattedError
|
|||||||
* Decorates spec-compliant $formattedError with debug entries according to $debug flags
|
* Decorates spec-compliant $formattedError with debug entries according to $debug flags
|
||||||
* (see GraphQL\Error\Debug for available flags)
|
* (see GraphQL\Error\Debug for available flags)
|
||||||
*
|
*
|
||||||
* @param array $formattedError
|
* @param mixed[] $formattedError
|
||||||
* @param \Throwable $e
|
* @param \Throwable $e
|
||||||
* @param bool $debug
|
* @param bool $debug
|
||||||
* @return array
|
* @return mixed[]
|
||||||
* @throws \Throwable
|
* @throws \Throwable
|
||||||
*/
|
*/
|
||||||
public static function addDebugEntries(array $formattedError, $e, $debug)
|
public static function addDebugEntries(array $formattedError, $e, $debug)
|
||||||
{
|
{
|
||||||
if (!$debug) {
|
if (! $debug) {
|
||||||
return $formattedError;
|
return $formattedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
Utils::invariant(
|
Utils::invariant(
|
||||||
$e instanceof \Exception || $e instanceof \Throwable,
|
$e instanceof \Exception || $e instanceof \Throwable,
|
||||||
"Expected exception, got %s",
|
'Expected exception, got %s',
|
||||||
Utils::getVariableType($e)
|
Utils::getVariableType($e)
|
||||||
);
|
);
|
||||||
|
|
||||||
$debug = (int) $debug;
|
$debug = (int) $debug;
|
||||||
|
|
||||||
if ($debug & Debug::RETHROW_INTERNAL_EXCEPTIONS) {
|
if ($debug & Debug::RETHROW_INTERNAL_EXCEPTIONS) {
|
||||||
if (!$e instanceof Error) {
|
if (! $e instanceof Error) {
|
||||||
throw $e;
|
throw $e;
|
||||||
} else if ($e->getPrevious()) {
|
}
|
||||||
|
|
||||||
|
if ($e->getPrevious()) {
|
||||||
throw $e->getPrevious();
|
throw $e->getPrevious();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$isInternal = !$e instanceof ClientAware || !$e->isClientSafe();
|
$isInternal = ! $e instanceof ClientAware || ! $e->isClientSafe();
|
||||||
|
|
||||||
if (($debug & Debug::INCLUDE_DEBUG_MESSAGE) && $isInternal) {
|
if (($debug & Debug::INCLUDE_DEBUG_MESSAGE) && $isInternal) {
|
||||||
// Displaying debugMessage as a first entry:
|
// Displaying debugMessage as a first entry:
|
||||||
@ -230,13 +262,14 @@ class FormattedError
|
|||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
$isTrivial = $e instanceof Error && !$e->getPrevious();
|
$isTrivial = $e instanceof Error && ! $e->getPrevious();
|
||||||
|
|
||||||
if (!$isTrivial) {
|
if (! $isTrivial) {
|
||||||
$debugging = $e->getPrevious() ?: $e;
|
$debugging = $e->getPrevious() ?: $e;
|
||||||
$formattedError['trace'] = static::toSafeTrace($debugging);
|
$formattedError['trace'] = static::toSafeTrace($debugging);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $formattedError;
|
return $formattedError;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,20 +277,20 @@ class FormattedError
|
|||||||
* Prepares final error formatter taking in account $debug flags.
|
* Prepares final error formatter taking in account $debug flags.
|
||||||
* If initial formatter is not set, FormattedError::createFromException is used
|
* If initial formatter is not set, FormattedError::createFromException is used
|
||||||
*
|
*
|
||||||
* @param callable|null $formatter
|
* @param bool $debug
|
||||||
* @param $debug
|
|
||||||
* @return callable|\Closure
|
* @return callable|\Closure
|
||||||
*/
|
*/
|
||||||
public static function prepareFormatter(callable $formatter = null, $debug)
|
public static function prepareFormatter(?callable $formatter = null, $debug)
|
||||||
{
|
{
|
||||||
$formatter = $formatter ?: function($e) {
|
$formatter = $formatter ?: function ($e) {
|
||||||
return FormattedError::createFromException($e);
|
return FormattedError::createFromException($e);
|
||||||
};
|
};
|
||||||
if ($debug) {
|
if ($debug) {
|
||||||
$formatter = function($e) use ($formatter, $debug) {
|
$formatter = function ($e) use ($formatter, $debug) {
|
||||||
return FormattedError::addDebugEntries($formatter($e), $e, $debug);
|
return FormattedError::addDebugEntries($formatter($e), $e, $debug);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return $formatter;
|
return $formatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -266,45 +299,45 @@ class FormattedError
|
|||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @param \Throwable $error
|
* @param \Throwable $error
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function toSafeTrace($error)
|
public static function toSafeTrace($error)
|
||||||
{
|
{
|
||||||
$trace = $error->getTrace();
|
$trace = $error->getTrace();
|
||||||
|
|
||||||
// Remove invariant entries as they don't provide much value:
|
if (isset($trace[0]['function']) && isset($trace[0]['class']) &&
|
||||||
if (
|
// Remove invariant entries as they don't provide much value:
|
||||||
isset($trace[0]['function']) && isset($trace[0]['class']) &&
|
($trace[0]['class'] . '::' . $trace[0]['function'] === 'GraphQL\Utils\Utils::invariant')) {
|
||||||
('GraphQL\Utils\Utils::invariant' === $trace[0]['class'].'::'.$trace[0]['function'])) {
|
array_shift($trace);
|
||||||
|
} elseif (! isset($trace[0]['file'])) {
|
||||||
|
// Remove root call as it's likely error handler trace:
|
||||||
array_shift($trace);
|
array_shift($trace);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove root call as it's likely error handler trace:
|
return array_map(
|
||||||
else if (!isset($trace[0]['file'])) {
|
function ($err) {
|
||||||
array_shift($trace);
|
$safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
|
||||||
}
|
|
||||||
|
|
||||||
return array_map(function($err) {
|
if (isset($err['function'])) {
|
||||||
$safeErr = array_intersect_key($err, ['file' => true, 'line' => true]);
|
$func = $err['function'];
|
||||||
|
$args = ! empty($err['args']) ? array_map([__CLASS__, 'printVar'], $err['args']) : [];
|
||||||
|
$funcStr = $func . '(' . implode(', ', $args) . ')';
|
||||||
|
|
||||||
if (isset($err['function'])) {
|
if (isset($err['class'])) {
|
||||||
$func = $err['function'];
|
$safeErr['call'] = $err['class'] . '::' . $funcStr;
|
||||||
$args = !empty($err['args']) ? array_map([__CLASS__, 'printVar'], $err['args']) : [];
|
} else {
|
||||||
$funcStr = $func . '(' . implode(", ", $args) . ')';
|
$safeErr['function'] = $funcStr;
|
||||||
|
}
|
||||||
if (isset($err['class'])) {
|
|
||||||
$safeErr['call'] = $err['class'] . '::' . $funcStr;
|
|
||||||
} else {
|
|
||||||
$safeErr['function'] = $funcStr;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return $safeErr;
|
return $safeErr;
|
||||||
}, $trace);
|
},
|
||||||
|
$trace
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param $var
|
* @param mixed $var
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public static function printVar($var)
|
public static function printVar($var)
|
||||||
@ -314,6 +347,7 @@ class FormattedError
|
|||||||
if ($var instanceof WrappingType) {
|
if ($var instanceof WrappingType) {
|
||||||
$var = $var->getWrappedType(true);
|
$var = $var->getWrappedType(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'GraphQLType: ' . $var->name;
|
return 'GraphQLType: ' . $var->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -323,7 +357,7 @@ class FormattedError
|
|||||||
if (is_array($var)) {
|
if (is_array($var)) {
|
||||||
return 'array(' . count($var) . ')';
|
return 'array(' . count($var) . ')';
|
||||||
}
|
}
|
||||||
if ('' === $var) {
|
if ($var === '') {
|
||||||
return '(empty string)';
|
return '(empty string)';
|
||||||
}
|
}
|
||||||
if (is_string($var)) {
|
if (is_string($var)) {
|
||||||
@ -335,42 +369,45 @@ class FormattedError
|
|||||||
if (is_scalar($var)) {
|
if (is_scalar($var)) {
|
||||||
return $var;
|
return $var;
|
||||||
}
|
}
|
||||||
if (null === $var) {
|
if ($var === null) {
|
||||||
return 'null';
|
return 'null';
|
||||||
}
|
}
|
||||||
|
|
||||||
return gettype($var);
|
return gettype($var);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @deprecated as of v0.8.0
|
* @deprecated as of v0.8.0
|
||||||
* @param $error
|
* @param string $error
|
||||||
* @param SourceLocation[] $locations
|
* @param SourceLocation[] $locations
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function create($error, array $locations = [])
|
public static function create($error, array $locations = [])
|
||||||
{
|
{
|
||||||
$formatted = [
|
$formatted = ['message' => $error];
|
||||||
'message' => $error
|
|
||||||
];
|
|
||||||
|
|
||||||
if (!empty($locations)) {
|
if (! empty($locations)) {
|
||||||
$formatted['locations'] = array_map(function($loc) { return $loc->toArray();}, $locations);
|
$formatted['locations'] = array_map(
|
||||||
|
function ($loc) {
|
||||||
|
return $loc->toArray();
|
||||||
|
},
|
||||||
|
$locations
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $formatted;
|
return $formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param \ErrorException $e
|
|
||||||
* @deprecated as of v0.10.0, use general purpose method createFromException() instead
|
* @deprecated as of v0.10.0, use general purpose method createFromException() instead
|
||||||
* @return array
|
* @return mixed[]
|
||||||
*/
|
*/
|
||||||
public static function createFromPHPError(\ErrorException $e)
|
public static function createFromPHPError(\ErrorException $e)
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'message' => $e->getMessage(),
|
'message' => $e->getMessage(),
|
||||||
'severity' => $e->getSeverity(),
|
'severity' => $e->getSeverity(),
|
||||||
'trace' => self::toSafeTrace($e)
|
'trace' => self::toSafeTrace($e),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -7,8 +10,6 @@ namespace GraphQL\Error;
|
|||||||
* Note:
|
* Note:
|
||||||
* This exception should not inherit base Error exception as it is raised when there is an error somewhere in
|
* This exception should not inherit base Error exception as it is raised when there is an error somewhere in
|
||||||
* user-land code
|
* user-land code
|
||||||
*
|
|
||||||
* @package GraphQL\Error
|
|
||||||
*/
|
*/
|
||||||
class InvariantViolation extends \LogicException
|
class InvariantViolation extends \LogicException
|
||||||
{
|
{
|
||||||
|
@ -1,19 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
use GraphQL\Language\Source;
|
use GraphQL\Language\Source;
|
||||||
|
use function sprintf;
|
||||||
|
|
||||||
class SyntaxError extends Error
|
class SyntaxError extends Error
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param Source $source
|
* @param int $position
|
||||||
* @param int $position
|
|
||||||
* @param string $description
|
* @param string $description
|
||||||
*/
|
*/
|
||||||
public function __construct(Source $source, $position, $description)
|
public function __construct(Source $source, $position, $description)
|
||||||
{
|
{
|
||||||
parent::__construct(
|
parent::__construct(
|
||||||
"Syntax Error: $description",
|
sprintf('Syntax Error: %s', $description),
|
||||||
null,
|
null,
|
||||||
$source,
|
$source,
|
||||||
[$position]
|
[$position]
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class UserError
|
* Class UserError
|
||||||
*
|
*
|
||||||
* Error caused by actions of GraphQL clients. Can be safely displayed to a client...
|
* Error caused by actions of GraphQL clients. Can be safely displayed to a client...
|
||||||
*
|
|
||||||
* @package GraphQL\Error
|
|
||||||
*/
|
*/
|
||||||
class UserError extends \RuntimeException implements ClientAware
|
class UserError extends \RuntimeException implements ClientAware
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
namespace GraphQL\Error;
|
namespace GraphQL\Error;
|
||||||
|
|
||||||
|
use const E_USER_WARNING;
|
||||||
|
use function trigger_error;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulates warnings produced by the library.
|
* Encapsulates warnings produced by the library.
|
||||||
*
|
*
|
||||||
@ -9,27 +15,29 @@ namespace GraphQL\Error;
|
|||||||
*/
|
*/
|
||||||
final class Warning
|
final class Warning
|
||||||
{
|
{
|
||||||
const WARNING_ASSIGN = 2;
|
const WARNING_ASSIGN = 2;
|
||||||
const WARNING_CONFIG = 4;
|
const WARNING_CONFIG = 4;
|
||||||
const WARNING_FULL_SCHEMA_SCAN = 8;
|
const WARNING_FULL_SCHEMA_SCAN = 8;
|
||||||
const WARNING_CONFIG_DEPRECATION = 16;
|
const WARNING_CONFIG_DEPRECATION = 16;
|
||||||
const WARNING_NOT_A_TYPE = 32;
|
const WARNING_NOT_A_TYPE = 32;
|
||||||
const ALL = 63;
|
const ALL = 63;
|
||||||
|
|
||||||
static $enableWarnings = self::ALL;
|
/** @var int */
|
||||||
|
private static $enableWarnings = self::ALL;
|
||||||
|
|
||||||
static $warned = [];
|
/** @var mixed[] */
|
||||||
|
private static $warned = [];
|
||||||
|
|
||||||
static private $warningHandler;
|
/** @var callable|null */
|
||||||
|
private static $warningHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets warning handler which can intercept all system warnings.
|
* Sets warning handler which can intercept all system warnings.
|
||||||
* When not set, trigger_error() is used to notify about warnings.
|
* When not set, trigger_error() is used to notify about warnings.
|
||||||
*
|
*
|
||||||
* @api
|
* @api
|
||||||
* @param callable|null $warningHandler
|
|
||||||
*/
|
*/
|
||||||
public static function setWarningHandler(callable $warningHandler = null)
|
public static function setWarningHandler(?callable $warningHandler = null)
|
||||||
{
|
{
|
||||||
self::$warningHandler = $warningHandler;
|
self::$warningHandler = $warningHandler;
|
||||||
}
|
}
|
||||||
@ -45,14 +53,15 @@ final class Warning
|
|||||||
* @api
|
* @api
|
||||||
* @param bool|int $suppress
|
* @param bool|int $suppress
|
||||||
*/
|
*/
|
||||||
static function suppress($suppress = true)
|
public static function suppress($suppress = true)
|
||||||
{
|
{
|
||||||
if (true === $suppress) {
|
if ($suppress === true) {
|
||||||
self::$enableWarnings = 0;
|
self::$enableWarnings = 0;
|
||||||
} else if (false === $suppress) {
|
} elseif ($suppress === false) {
|
||||||
self::$enableWarnings = self::ALL;
|
self::$enableWarnings = self::ALL;
|
||||||
} else {
|
} else {
|
||||||
$suppress = (int) $suppress;
|
$suppress = (int) $suppress;
|
||||||
|
|
||||||
self::$enableWarnings &= ~$suppress;
|
self::$enableWarnings &= ~$suppress;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,33 +79,34 @@ final class Warning
|
|||||||
*/
|
*/
|
||||||
public static function enable($enable = true)
|
public static function enable($enable = true)
|
||||||
{
|
{
|
||||||
if (true === $enable) {
|
if ($enable === true) {
|
||||||
self::$enableWarnings = self::ALL;
|
self::$enableWarnings = self::ALL;
|
||||||
} else if (false === $enable) {
|
} elseif ($enable === false) {
|
||||||
self::$enableWarnings = 0;
|
self::$enableWarnings = 0;
|
||||||
} else {
|
} else {
|
||||||
$enable = (int) $enable;
|
$enable = (int) $enable;
|
||||||
|
|
||||||
self::$enableWarnings |= $enable;
|
self::$enableWarnings |= $enable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function warnOnce($errorMessage, $warningId, $messageLevel = null)
|
public static function warnOnce($errorMessage, $warningId, $messageLevel = null)
|
||||||
{
|
{
|
||||||
if (self::$warningHandler) {
|
if (self::$warningHandler) {
|
||||||
$fn = self::$warningHandler;
|
$fn = self::$warningHandler;
|
||||||
$fn($errorMessage, $warningId);
|
$fn($errorMessage, $warningId);
|
||||||
} else if ((self::$enableWarnings & $warningId) > 0 && !isset(self::$warned[$warningId])) {
|
} elseif ((self::$enableWarnings & $warningId) > 0 && ! isset(self::$warned[$warningId])) {
|
||||||
self::$warned[$warningId] = true;
|
self::$warned[$warningId] = true;
|
||||||
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
|
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static function warn($errorMessage, $warningId, $messageLevel = null)
|
public static function warn($errorMessage, $warningId, $messageLevel = null)
|
||||||
{
|
{
|
||||||
if (self::$warningHandler) {
|
if (self::$warningHandler) {
|
||||||
$fn = self::$warningHandler;
|
$fn = self::$warningHandler;
|
||||||
$fn($errorMessage, $warningId);
|
$fn($errorMessage, $warningId);
|
||||||
} else if ((self::$enableWarnings & $warningId) > 0) {
|
} elseif ((self::$enableWarnings & $warningId) > 0) {
|
||||||
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
|
trigger_error($errorMessage, $messageLevel ?: E_USER_WARNING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user