https://github.com/mixerapi/exception-render
Handles rendering entity validation errors and other exceptions for your API [READ-ONLY]
https://github.com/mixerapi/exception-render
cakephp exception-handling php
Last synced: 8 months ago
JSON representation
Handles rendering entity validation errors and other exceptions for your API [READ-ONLY]
- Host: GitHub
- URL: https://github.com/mixerapi/exception-render
- Owner: mixerapi
- License: other
- Created: 2020-08-23T16:13:07.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-03-25T23:50:22.000Z (almost 2 years ago)
- Last Synced: 2025-04-22T12:07:57.088Z (8 months ago)
- Topics: cakephp, exception-handling, php
- Language: PHP
- Homepage: https://mixerapi.com/plugins/exception-render
- Size: 53.7 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# MixerAPI ExceptionRender
[](https://packagist.org/packages/mixerapi/exception-render)
[](https://github.com/mixerapi/mixerapi-dev/actions?query=workflow%3ABuild)
[](https://coveralls.io/github/mixerapi/mixerapi-dev?branch=master)
[](http://mixerapi.com)
[](https://book.cakephp.org/4/en/index.html)
[](https://php.net/)
This plugin handles rendering entity validation errors and other exceptions for your API.
- Integrates with [Validator](https://book.cakephp.org/4/en/core-libraries/validation.html) on `add()` and `edit()`
actions.
- Adds the short name of the Exception thrown to the response
Read more at [MixerAPI.com](https://mixerapi.com).
## Installation
!!! tip ""
You can skip this step if you have MixerApi installed.
```console
composer require mixerapi/exception-render
bin/cake plugin load MixerApi/ExceptionRender
```
Alternatively after composer installing you can manually load the plugin in your Application:
```php
# src/Application.php
public function bootstrap(): void
{
// other logic...
$this->addPlugin('MixerApi/ExceptionRender');
}
```
## Setup
In your `config/app.php` file change the default `exceptionRenderer`:
```php
'Error' => [
'errorLevel' => E_ALL,
'exceptionRenderer' => MixerApi\ExceptionRender\MixerApiExceptionRenderer::class,
'skipLog' => [],
'log' => true,
'trace' => true,
],
```
## Usage
Define your Validations as normal in your Table classes and `MixerApiExceptionRenderer` handles the rest by attaching
a listener to the [afterMarshall](https://book.cakephp.org/4/en/orm/table-objects.html#aftermarshal) event which fires
when request data is merged into entities during patchEntity() or newEntity() calls. If a validation fails then a
`ValidationException` is thrown and rendered with an HTTP 422 status code.
Example controller action:
```php
public function add()
{
$this->request->allowMethod('post');
$actor = $this->Actors->newEmptyEntity();
$actor = $this->Actors->patchEntity($actor, $this->request->getData()); // potential ValidationException here
if ($this->Actors->save($actor)) {
$this->viewBuilder()->setOption('serialize', 'actor');
$this->set('actor', $actor);
return;
}
throw new \Exception("Record failed to save");
}
```
Output:
```json
{
"exception": "ValidationException",
"message": "Error saving resource `Actor`",
"url": "/actors",
"code": 422,
"violations": [
{
"propertyPath": "first_name",
"messages": [
{
"rule": "_required",
"message": "This field is required"
}
]
},
{
"propertyPath": "last_name",
"messages": [
{
"rule": "_required",
"message": "This field is required"
}
]
}
]
}
```
Using the controller example from above, we can catch the exception if desired and perform additional logic:
```php
try {
$actor = $this->Actors->newEmptyEntity();
$actor = $this->Actors->patchEntity($actor, $this->request->getData());
} catch (\MixerApi\ExceptionRender\ValidationException $e) {
// do something here
}
```
### Exceptions
For non-validation based exceptions, even your projects own custom exceptions, the output is similar to CakePHP native
output with the addition of an exception attribute. For example, a `MethodNotAllowedException` would result in:
```json
{
"exception": "MethodNotAllowedException",
"message": "Your exception message here",
"url": "/actors",
"code": 405
}
```
If for instance you have a custom exception that is thrown, such as `InventoryExceededException`, you would see:
```json
{
"exception": "InventoryExceededException",
"message": "No inventory exists",
"url": "/requested-url",
"code": 500
}
```
Providing an Exception name, in conjunction with the status code already provided by CakePHP, enables API clients
to tailor their exception handling.
### Disabling ValidationExceptions
There may be times when you don't want ValidationExceptions to run. You can easily disable the event:
```php
Configure::write('MixerApi.ExceptionRender.entity_validation', false);
```
Another example is you may only want the event to run for non-CLI portions of your application:
```php
Configure::write('MixerApi.ExceptionRender.entity_validation', PHP_SAPI !== 'cli');
```
### Changing Error Messages
ExceptionRender dispatches a `MixerApi.ExceptionRender.beforeRender` event that you can listen for to alter `viewVars`
and `serialize` variables. Both are accessible via the `MixerApi\ExceptionRender\ErrorDecorator`.
Example:
```php
'beforeRender'
];
}
/**
* @param \Cake\Event\Event $event
*/
public function beforeRender(\Cake\Event\Event $event)
{
$errorDecorator = $event->getSubject();
$data = $event->getData();
if (!$errorDecorator instanceof ErrorDecorator || !$data['exception'] instanceof MixerApiExceptionRenderer) {
return;
}
if (!$data['exception']->getError() instanceof \Authentication\Authenticator\UnauthenticatedException) {
return;
}
$viewVars = $errorDecorator->getViewVars();
$viewVars['message'] = 'A custom unauthenticated message';
$errorDecorator->setViewVars($viewVars);
}
}
```
Read more about [Events](https://book.cakephp.org/4/en/core-libraries/events.html) in the official CakePHP documentation.