Skip to content

Commit

Permalink
More graceful exception handling
Browse files Browse the repository at this point in the history
  • Loading branch information
chillu committed Sep 24, 2016
1 parent 593a12e commit f9955b0
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 58 deletions.
22 changes: 20 additions & 2 deletions src/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Core\Injector\Injector;
use SilverStripe\Core\Config\Config;
use SilverStripe\Control\Director;
use Exception;

class Controller extends BaseController
{
Expand Down Expand Up @@ -37,9 +39,25 @@ public function index(HTTPRequest $request)
}

$manager = $this->getManager();
$response = $manager->query($query, $variables);

return (new HTTPResponse(json_encode($response)))
try {
$result = $manager->query($query, $variables);
} catch (Exception $exception) {
$error = ['message' => $exception->getMessage()];

if(Director::isDev()) {
$error['code'] = $exception->getCode();
$error['file'] = $exception->getFile();
$error['line'] = $exception->getLine();
$error['trace'] = $exception->getTrace();
}

$result = [
'errors' => [$error]
];
}

return (new HTTPResponse(json_encode($result)))
->addHeader('Content-Type', 'application/json');
}

Expand Down
59 changes: 59 additions & 0 deletions tests/ControllerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@
use Chillu\GraphQL\Tests\Fake\TypeCreatorFake;
use Chillu\GraphQL\Tests\Fake\QueryCreatorFake;
use SilverStripe\Core\Config\Config;
use GraphQL\Schema;
use GraphQL\Type\Definition\ObjectType;
use ReflectionClass;
use Exception;

class ControllerTest extends SapphireTest
{
Expand Down Expand Up @@ -43,6 +46,62 @@ public function testGetGetManagerPopulatesFromConfig()
);
}

public function testIndexWithException()
{
Config::inst()->update('SilverStripe\\Control\\Director', 'environment_type', 'live');

$controller = new Controller();
$managerMock = $this->getMockBuilder(Schema::class)
->setMethods(['query'])
->setConstructorArgs([
['query' => new ObjectType([
'name' => 'Query',
'fields' => []
])]
])
->getMock();

$managerMock->method('query')
->will($this->throwException(new Exception('Failed')));

$controller->setManager($managerMock);
$response = $controller->index(new HTTPRequest('GET', ''));
$this->assertFalse($response->isError());
$responseObj = json_decode($response->getBody(), true);
$this->assertNotNull($responseObj);
$this->assertArrayHasKey('errors', $responseObj);
$this->assertEquals('Failed', $responseObj['errors'][0]['message']);
$this->assertArrayNotHasKey('trace', $responseObj['errors'][0]);
}

public function testIndexWithExceptionIncludesTraceInDevMode()
{
Config::inst()->update('SilverStripe\\Control\\Director', 'environment_type', 'dev');

$controller = new Controller();
$managerMock = $this->getMockBuilder(Schema::class)
->setMethods(['query'])
->setConstructorArgs([
['query' => new ObjectType([
'name' => 'Query',
'fields' => []
])]
])
->getMock();

$managerMock->method('query')
->will($this->throwException(new Exception('Failed')));

$controller->setManager($managerMock);
$response = $controller->index(new HTTPRequest('GET', ''));
$this->assertFalse($response->isError());
$responseObj = json_decode($response->getBody(), true);
$this->assertNotNull($responseObj);
$this->assertArrayHasKey('errors', $responseObj);
$this->assertEquals('Failed', $responseObj['errors'][0]['message']);
$this->assertArrayHasKey('trace', $responseObj['errors'][0]);
}

protected function getType(Manager $manager)
{
return (new TypeCreatorFake($manager))->toType();
Expand Down
56 changes: 0 additions & 56 deletions tests/Resolver/DataObjectLowerCamelResolverTest.php

This file was deleted.

0 comments on commit f9955b0

Please sign in to comment.