CakePHP 4.x
We have an application which consists of a frontend web app (used by customers through a browser) and an API for some backend operations which is integrated with our other systems.
The code is in the expected places i.e. src/Controller/
has the Controller’s for the web app requests. In src/Controller/Api/V1/
we have our API.
The problem is if we get some error with the API such as a 404, CakePHP seems to automatically render a HTML error page.
My limited understanding of this is that in config/app.php
you have this by default
'exceptionRenderer' => 'CakeErrorExceptionRenderer',
You can replace that with your own
'exceptionRenderer' => AppErrorApiErrorRenderer::class,
Then have your own custom class for it.
<?php
// src/Error/ApiErrorRenderer.php
declare(strict_types=1);
namespace AppError;
use CakeErrorRendererWebExceptionRenderer;
use CakeHttpResponse;
class ApiErrorRenderer extends WebExceptionRenderer
{
/**
* Render the exception.
*
* @return CakeHttpResponse The response object.
*/
public function render(): Response
{
$response = parent::render();
// Set the content type to application/json for all API errors
return $response->withType('application/json');
}
}
The problem is that now returns a JSON response for all errors, including the 404’s for the web app. So it doesn’t render as HTML in the browser for customers, though the API now has JSON responses for it’s errors.
In phpunit it’s common to have tests that include checks such as $this->assertContentType('application/json');
before testing responses – which might include errors – from an API.
Without such changes above those tests fail because HTML rather than JSON is returned. But with the fix in place, that breaks the web app for customers.
This seems like something that should be simple and included in the framework as it’s so obvious that in both of those 2 different environments (web app vs API) you’d typically be using HTML and JSON responses respectively.