graphql-php/src/Error.php

133 lines
3.1 KiB
PHP
Raw Normal View History

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
*/
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
* @return array
2015-08-16 16:39:30 +06:00
*/
public static function formatError(Error $error)
{
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
*/
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);
if ($nodes instanceof \Traversable) {
$nodes = iterator_to_array($nodes);
}
2015-08-16 16:39:30 +06:00
$this->nodes = $nodes;
$this->source = $source;
$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
}
}