Merge pull request #51 from silverstripe-terraformers/feature/catch-exception-and-extension-points

Added general Exception catch/response. Added extension points to response methods
This commit is contained in:
Robbie Averill 2018-04-04 15:34:05 +12:00 committed by GitHub
commit 5f7861e0ac
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 126 additions and 16 deletions

View File

@ -154,21 +154,25 @@ class RestfulServer extends Controller
// authenticate through HTTP BasicAuth
$this->member = $this->authenticate();
// handle different HTTP verbs
if ($this->request->isGET() || $this->request->isHEAD()) {
return $this->getHandler($className, $id, $relation);
}
try {
// handle different HTTP verbs
if ($this->request->isGET() || $this->request->isHEAD()) {
return $this->getHandler($className, $id, $relation);
}
if ($this->request->isPOST()) {
return $this->postHandler($className, $id, $relation);
}
if ($this->request->isPOST()) {
return $this->postHandler($className, $id, $relation);
}
if ($this->request->isPUT()) {
return $this->putHandler($className, $id, $relation);
}
if ($this->request->isPUT()) {
return $this->putHandler($className, $id, $relation);
}
if ($this->request->isDELETE()) {
return $this->deleteHandler($className, $id, $relation);
if ($this->request->isDELETE()) {
return $this->deleteHandler($className, $id, $relation);
}
} catch (\Exception $e) {
return $this->exceptionThrown($this->getRequestDataFormatter($className), $e);
}
// if no HTTP verb matches, return error
@ -681,7 +685,11 @@ class RestfulServer extends Controller
$this->getResponse()->setStatusCode(401);
$this->getResponse()->addHeader('WWW-Authenticate', 'Basic realm="API Access"');
$this->getResponse()->addHeader('Content-Type', 'text/plain');
return "You don't have access to this item through the API.";
$reponse = "You don't have access to this item through the API.";
$this->extend(__FUNCTION__, $reponse);
return $reponse;
}
/**
@ -692,7 +700,11 @@ class RestfulServer extends Controller
// return a 404
$this->getResponse()->setStatusCode(404);
$this->getResponse()->addHeader('Content-Type', 'text/plain');
return "That object wasn't found";
$reponse = "That object wasn't found";
$this->extend(__FUNCTION__, $reponse);
return $reponse;
}
/**
@ -702,7 +714,11 @@ class RestfulServer extends Controller
{
$this->getResponse()->setStatusCode(405);
$this->getResponse()->addHeader('Content-Type', 'text/plain');
return "Method Not Allowed";
$reponse = "Method Not Allowed";
$this->extend(__FUNCTION__, $reponse);
return $reponse;
}
/**
@ -712,7 +728,11 @@ class RestfulServer extends Controller
{
$this->response->setStatusCode(415); // Unsupported Media Type
$this->getResponse()->addHeader('Content-Type', 'text/plain');
return "Unsupported Media Type";
$reponse = "Unsupported Media Type";
$this->extend(__FUNCTION__, $reponse);
return $reponse;
}
/**
@ -729,6 +749,28 @@ class RestfulServer extends Controller
'messages' => $result->getMessages(),
];
$this->extend(__FUNCTION__, $response, $result);
return $responseFormatter->convertArray($response);
}
/**
* @param DataFormatter $responseFormatter
* @param \Exception $e
* @return string
*/
protected function exceptionThrown(DataFormatter $responseFormatter, \Exception $e)
{
$this->getResponse()->setStatusCode(500);
$this->getResponse()->addHeader('Content-Type', $responseFormatter->getOutputContentType());
$response = [
'type' => get_class($e),
'message' => $e->getMessage(),
];
$this->extend(__FUNCTION__, $response, $e);
return $responseFormatter->convertArray($response);
}

View File

@ -3,6 +3,7 @@
namespace SilverStripe\RestfulServer\Tests;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestComment;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestExceptionThrown;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestSecretThing;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestPage;
use SilverStripe\RestfulServer\Tests\Stubs\RestfulServerTestAuthor;
@ -38,6 +39,8 @@ class RestfulServerTest extends SapphireTest
RestfulServerTestPage::class,
RestfulServerTestAuthor::class,
RestfulServerTestAuthorRating::class,
RestfulServerTestValidationFailure::class,
RestfulServerTestExceptionThrown::class,
];
protected function urlSafeClassname($classname)
@ -685,4 +688,17 @@ class RestfulServerTest extends SapphireTest
$responseArr = Convert::xml2array($response->getBody());
$this->assertEquals('SilverStripe\\ORM\\ValidationException', $responseArr['type']);
}
public function testExceptionThrownWithPOST()
{
$urlSafeClassname = $this->urlSafeClassname(RestfulServerTestExceptionThrown::class);
$url = "{$this->baseURI}/api/v1/$urlSafeClassname/";
$data = [
'Content' => 'Test',
];
$response = Director::test($url, $data, null, 'POST');
// Assumption: XML is default output
$responseArr = Convert::xml2array($response->getBody());
$this->assertEquals(\Exception::class, $responseArr['type']);
}
}

View File

@ -0,0 +1,52 @@
<?php
namespace SilverStripe\RestfulServer\Tests\Stubs;
use SilverStripe\Dev\TestOnly;
use SilverStripe\ORM\DataObject;
/**
* Class RestfulServerTestExceptionThrown
* @package SilverStripe\RestfulServer\Tests\Stubs
*
* @property string Content
* @property string Title
*/
class RestfulServerTestExceptionThrown extends DataObject implements TestOnly
{
private static $api_access = true;
private static $table_name = 'RestfulServerTestExceptionThrown';
private static $db = array(
'Content' => 'Text',
'Title' => 'Text',
);
public function onBeforeWrite()
{
parent::onBeforeWrite();
throw new \Exception('This is an exception test');
}
public function canView($member = null)
{
return true;
}
public function canEdit($member = null)
{
return true;
}
public function canDelete($member = null)
{
return true;
}
public function canCreate($member = null, $context = array())
{
return true;
}
}