Buy

Creating the Invalid JSON ApiProblem, and then...

The nice API Problem JSON format always has a type key, so let's at least start looking for that in the response. Use $this->asserter()->assertResponsePropertyEquals() and pass it the $response and type as the key. For the value - how about invalid_body_format. That's our second special error "type" - the first was validation_error.

168 lines src/AppBundle/Tests/Controller/Api/ProgrammerControllerTest.php
... lines 1 - 5
class ProgrammerControllerTest extends ApiTestCase
{
... lines 8 - 147
public function testInvalidJson()
{
... lines 150 - 162
$this->assertEquals(400, $response->getStatusCode());
$this->asserter()->assertResponsePropertyEquals($response, 'type', 'invalid_body_format');
}
... line 166
}

This should get our test to fail again:

./bin/phpunit -c app --filter testInvalidJson

Gooood - we're still returning the exception HTML.

Creating the ApiProblem

Let's fix this just like we did for validation errors: by creating an ApiProblem object. First, we need a new type constant. Create a second constant called TYPE_INVALID_REQUEST_BODY_FORMAT and set that to the string from our test: invalid_body_format. Setup a title for this too: how about "Invalid JSON format sent". And I better fix my syntax error:

60 lines src/AppBundle/Api/ApiProblem.php
... lines 1 - 7
class ApiProblem
{
const TYPE_VALIDATION_ERROR = 'validation_error';
const TYPE_INVALID_REQUEST_BODY_FORMAT = 'invalid_body_format';
private static $titles = array(
self::TYPE_VALIDATION_ERROR => 'There was a validation error',
self::TYPE_INVALID_REQUEST_BODY_FORMAT => 'Invalid JSON format sent',
);
... lines 17 - 58
}

Back in ProgrammerController, we can get to work: $apiProblem = new ApiProblem(). Pass it the 400 status code and the type: ApiProblem::TYPE_INVALID_REQUEST_BODY_FORMAT:

189 lines src/AppBundle/Controller/Api/ProgrammerController.php
... lines 1 - 17
class ProgrammerController extends BaseController
{
... lines 20 - 141
private function processForm(Request $request, FormInterface $form)
{
$data = json_decode($request->getContent(), true);
if ($data === null) {
$apiProblem = new ApiProblem(400, ApiProblem::TYPE_INVALID_REQUEST_BODY_FORMAT);
... lines 147 - 148
}
... lines 150 - 152
}
... lines 154 - 187
}

We're stuck

Gosh, everything is going really well! And now we're stuck. For validation, we took the ApiProblem, turned it into a Response and returned it. But inside processForm(), we're big trouble: the return value of this method isn't being used. We can only throw an exception to stop the flow. And while we can control the status code of an exception, the response body that an HttpException generates is still an HTML error page.

Leave a comment!