Added general Exception catch/response. Added extension points to all response methods.

This commit is contained in:
cpenny 2018-03-07 11:41:27 +13:00
parent c30b72e058
commit 44c5b45748
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
@ -664,7 +668,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;
}
/**
@ -675,7 +683,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;
}
/**
@ -685,7 +697,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;
}
/**
@ -695,7 +711,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;
}
/**
@ -712,6 +732,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;
@ -37,6 +38,8 @@ class RestfulServerTest extends SapphireTest
RestfulServerTestPage::class,
RestfulServerTestAuthor::class,
RestfulServerTestAuthorRating::class,
RestfulServerTestValidationFailure::class,
RestfulServerTestExceptionThrown::class,
];
protected function urlSafeClassname($classname)
@ -586,4 +589,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;
}
}