2015-07-15 23:05:46 +06:00
|
|
|
<?php
|
|
|
|
namespace GraphQL;
|
|
|
|
|
|
|
|
use GraphQL\Language\Source;
|
|
|
|
|
2015-08-16 16:39:30 +06:00
|
|
|
// /graphql-js/src/error/GraphQLError.js
|
2015-07-15 23:05:46 +06:00
|
|
|
|
|
|
|
class Error extends \Exception
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @var string
|
|
|
|
*/
|
|
|
|
public $message;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
|
|
|
public $nodes;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array
|
|
|
|
*/
|
2015-08-16 16:39:30 +06:00
|
|
|
private $positions;
|
2015-07-15 23:05:46 +06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array<SourceLocation>
|
|
|
|
*/
|
2015-08-16 16:39:30 +06:00
|
|
|
private $locations;
|
2015-07-15 23:05:46 +06:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Source|null
|
|
|
|
*/
|
2015-08-16 16:39:30 +06:00
|
|
|
private $source;
|
2015-07-15 23:05:46 +06:00
|
|
|
|
|
|
|
/**
|
2015-08-16 16:39:30 +06:00
|
|
|
* Given an arbitrary Error, presumably thrown while attempting to execute a
|
|
|
|
* GraphQL operation, produce a new GraphQLError aware of the location in the
|
|
|
|
* document responsible for the original Error.
|
|
|
|
*
|
2015-07-15 23:05:46 +06:00
|
|
|
* @param $error
|
2015-08-16 16:39:30 +06:00
|
|
|
* @param array|null $nodes
|
|
|
|
* @return Error
|
2015-07-15 23:05:46 +06:00
|
|
|
*/
|
2015-08-17 02:53:11 +06:00
|
|
|
public static function createLocatedError($error, $nodes = null)
|
2015-07-15 23:05:46 +06:00
|
|
|
{
|
2015-08-16 16:39:30 +06:00
|
|
|
if ($error instanceof \Exception) {
|
|
|
|
$message = $error->getMessage();
|
|
|
|
$previous = $error;
|
2015-07-15 23:05:46 +06:00
|
|
|
} else {
|
|
|
|
$message = (string) $error;
|
2015-08-16 16:39:30 +06:00
|
|
|
$previous = null;
|
2015-07-15 23:05:46 +06:00
|
|
|
}
|
|
|
|
|
2015-08-16 16:39:30 +06:00
|
|
|
return new Error($message, $nodes, $previous);
|
2015-07-15 23:05:46 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2015-08-16 16:39:30 +06:00
|
|
|
* @param Error $error
|
2015-08-17 02:53:11 +06:00
|
|
|
* @return array
|
2015-08-16 16:39:30 +06:00
|
|
|
*/
|
|
|
|
public static function formatError(Error $error)
|
|
|
|
{
|
2015-08-17 02:53:11 +06:00
|
|
|
return FormattedError::create($error->getMessage(), $error->getLocations());
|
2015-08-16 16:39:30 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string|\Exception $message
|
2015-07-15 23:05:46 +06:00
|
|
|
* @param array|null $nodes
|
2015-08-16 16:39:30 +06:00
|
|
|
* @param Source $source
|
|
|
|
* @param null $positions
|
|
|
|
*/
|
2015-08-17 02:53:11 +06:00
|
|
|
public function __construct($message, $nodes = null, \Exception $previous = null, Source $source = null, $positions = null)
|
2015-08-16 16:39:30 +06:00
|
|
|
{
|
|
|
|
parent::__construct($message, 0, $previous);
|
|
|
|
|
2015-08-17 02:53:11 +06:00
|
|
|
if ($nodes instanceof \Traversable) {
|
|
|
|
$nodes = iterator_to_array($nodes);
|
|
|
|
}
|
|
|
|
|
2015-08-16 16:39:30 +06:00
|
|
|
$this->nodes = $nodes;
|
|
|
|
$this->source = $source;
|
2015-08-17 02:53:11 +06:00
|
|
|
$this->positions = $positions;
|
2015-08-16 16:39:30 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return Source|null
|
2015-07-15 23:05:46 +06:00
|
|
|
*/
|
2015-08-16 16:39:30 +06:00
|
|
|
public function getSource()
|
2015-07-15 23:05:46 +06:00
|
|
|
{
|
2015-08-16 16:39:30 +06:00
|
|
|
if (null === $this->source) {
|
|
|
|
if (!empty($this->nodes[0]) && !empty($this->nodes[0]->loc)) {
|
|
|
|
$this->source = $this->nodes[0]->loc->source;
|
2015-07-15 23:05:46 +06:00
|
|
|
}
|
|
|
|
}
|
2015-08-16 16:39:30 +06:00
|
|
|
return $this->source;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array
|
|
|
|
*/
|
|
|
|
public function getPositions()
|
|
|
|
{
|
|
|
|
if (null === $this->positions) {
|
|
|
|
if (!empty($this->nodes)) {
|
|
|
|
$positions = array_map(function($node) { return isset($node->loc) ? $node->loc->start : null; }, $this->nodes);
|
|
|
|
$this->positions = array_filter($positions);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $this->positions;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array<SourceLocation>
|
|
|
|
*/
|
|
|
|
public function getLocations()
|
|
|
|
{
|
|
|
|
if (null === $this->locations) {
|
|
|
|
$positions = $this->getPositions();
|
|
|
|
$source = $this->getSource();
|
|
|
|
|
|
|
|
if ($positions && $source) {
|
|
|
|
$this->locations = array_map(function ($pos) use ($source) {
|
|
|
|
return $source->getLocation($pos);
|
|
|
|
}, $positions);
|
|
|
|
} else {
|
|
|
|
$this->locations = [];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->locations;
|
2015-07-15 23:05:46 +06:00
|
|
|
}
|
|
|
|
}
|