Exceptions
#
DefinitionExceptions are classes the handles errors, and helps developers debug their code in a more efficient way.
#
Principles- Exceptions can be thrown from anywhere in the application.
- Exceptions SHOULD be created inside the Containers. However, general Exceptions CAN be created in the
Ship
layer.
#
Rules- All Exceptions MUST extend
App\Ship\Parents\Exceptions\Exception
. - Shared (general) Exceptions between all Containers SHOULD be created in the Exceptions Ship folder (
app/Ship/Exceptions/*
). - Every Exception SHOULD have two properties
httpStatusCode
andmessage
, both properties will be displayed when an error occurs. You can override those values while throwing the error.
#
Folder Structure - App - Containers - {container-name} - Exceptions - AccountFailedException.php - ...
- Ship - Exceptions - IncorrectIdException.php - InternalErrorException.php - ...
#
Code SamplesUser Exception
:
<?php
namespace App\Containers\User\Exceptions;
use App\Ship\Parents\Exceptions\Exception;use Symfony\Component\HttpFoundation\Response;
class AccountFailedException extends Exception{ public $httpStatusCode = Response::HTTP_CONFLICT;
public $message = 'Failed creating new User.'; public $code = 4711;}
General Exception
:
<?php
namespace App\Ship\Exceptions;
use App\Ship\Parents\Exceptions\Exception;use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
class InternalErrorException extends Exception{ public $httpStatusCode = SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR;
public $message = 'Something went wrong!';}
General Exception
with CustomData:
<?php
namespace App\Ship\Exceptions;
use App\Ship\Parents\Exceptions\Exception;use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
class AwesomeExceptionWithCustomData extends Exception{ public $httpStatusCode = SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR;
public $message = 'Something went wrong!'; public $code = 1234; /* * Everything you add here will be automatically added to the ExceptionFormatter on the top level! * You can define any structure you want or maybe include translated messages */ public function addCustomData() { return [ 'title' => 'nice', 'description' => 'one fancy description here', 'foo' => true, 'meta' => [ 'bar' => 1234, ] ]; }}
Exception usage from anywhere:
<?php
throw new AccountFailedException();
Usage with Log for Debugging:
<?php
throw (new AccountFailedException())->debug($e); // debug() accepts string or \Exception instance
Usage and overriding the default message
:
<?php
throw new AccountFailedException('I am the message to be displayed for the user');
Usage and overwriting pre-set CustomData
<?php
throw (new AwesomeExceptionWithCustomData())->overrideCustomData(['foo' => 'bar']);
#
Application Error CodesApiato provides a convenient way to manage all application error codes
in one central place. Therefore, Apiato provides, amongst others, the \App\Ship\Exceptions\Codes\ApplicationErrorCodesTable
class, which already holds various information for multiple errors.
Thereby, one error look like this:
const BASE_GENERAL_ERROR = [ 'code' => 1001, 'title' => 'Unknown / Unspecified Error.', 'description' => 'Something unexpected happened.',];
Note that the code
is used to be sent back to the client. The title
and description
, however, can be used to automatically generate a documentation regarding all defined error codes and their meaning. Please note that this feature is currently not implemented but will be added later on.
#
Linking Exceptions and Error CodesIn order to link an error code
to an Exception
, you simply need override the useErrorCode()
method of the Exception
.
Consider the following example:
class InternalErrorException extends Exception{
public $httpStatusCode = SymfonyResponse::HTTP_INTERNAL_SERVER_ERROR;
public $message = 'Something went wrong!'; public code = 4711; // this code will be overwritten by the useErrorCode() method!
public function useErrorCode() { return ApplicationErrorCodes::BASE_INTERNAL_ERROR; }}
Please note that already defined $code
values may be overwritten by the useErrorCode()
method! Furthermore, this feature is completely optional - you may still use the known public $code = 4711;
approach to manually set an error code.
#
Defining Own Error Code TablesOf course, Apiato allows you to define your own CustomErrorCodesTable
. In fact, there already exists such a file where you can define your own error codes. Please note that the ApplicationErrorCodesTable
may be adapted by Apiato - the others will not.
If you like to split the errors in various files, you can easily create a UserErrorCodesTable
in respective namespace and define the errors accordingly. However, you need to manually "register" this code table. This can be achieved in the ErrorCodeManager::getCodeTables()
method.
Now you can easily use your UserErrorCodesTable::USER_NOT_VERIFIED
error in your Exception
class.