Nikola Poša
Web developer and software architect specializing in PHP based applications and web services.
Web developer & Open-Source Contributor
class ArticleService
{
public function getArticle(string $id)
{
$article = $this->repository->findBy('id', $id).first();
if (!$this->getPermissionsService()->can('read', $article)) {
return null;
}
return $article;
}
}
class ArticleService
{
public function getArticle(string $id) : Article
{
$article = $this->repository->findBy('id', $id).first();
if (!$this->getPermissionsService()->can('read', $article)) {
throw new InsufficientPermissionsException();
}
return $article;
}
}
throw an exception
class ArticleService
{
public function getArticle(string $id)
{
$articles = $this->repository->findBy('id', $id);
if ($articles.isEmpty()) {
return null;
}
$article = $articles.first();
if (!$this->getPermissionsService()->can('read', $article)) {
return null;
}
return $article;
}
}
class ArticleService
{
/**
* @param string $id
* @throws ArticleNotFoundException
* @throws InsufficientPermissionsException
* @return Article
*/
public function getArticle(string $id) : Article
{
$articles = $this->repository->findBy('id', $id);
if ($articles.isEmpty()) {
throw new ArticleNotFoundException();
}
$article = $articles.first();
if (!$this->getPermissionsService()->can('read', $article)) {
throw new InsufficientPermissionsException();
}
return $article;
}
}
throw an exception
return Special Case object
special/custom version of a on object that is returned in a normal flow
public function getArticle(string $id) : Article
{
$articles = $this->repository->findBy('id', $id);
if ($articles.isEmpty()) {
return new NonexistentArticle();
}
$article = $articles.first();
return $article;
}
class Article
{
//...
}
class NonexistentArticle extends Article
{
public function getTitle()
{
return 'Not found';
}
public function getContent()
{
return 'Go back to <a href="/">Home Page</a>';
}
}
throw new \Exception('Article with the ID: ' . $id . ' does not exist');
class ArticleNotFoundException extends RuntimeException
{
}
//...
throw new ArticleNotFoundException('Article with the ID: ' . $id . ' does not exist');
class ArticleNotFoundException extends RuntimeException
{
public static function forId(string $id) : self
{
return new self(sprintf(
'Article with the ID: %s does not exist',
$id
));
}
}
//...
throw ArticleNotFoundException::forId($id);
class InsufficientPermissionsException extends RuntimeException
{
private $entity;
private $privilege;
public static function forEntityAndPrivilege(
EntityInterface $entity,
string $privilege
) : self {
$exception = new self(sprintf(
'You do not have permission to %s %s with the id: %s',
$privilege,
get_class($entity),
$entity->getId()
));
$exception->entity = $entity;
$exception->privilege = $privilege;
return $exception;
}
public function getEntity() : EntityInterface
{
return $this->entity;
}
public function getPrivilege() : string
{
return $this->privilege;
}
}
class UserException extends Exception
{
public static function forEmptyEmail() : self
{
return new self("User's email must not be empty");
}
public static function forInvalidEmail(string $email) : self
{
return new self(sprintf(
'%s is not a valid email address',
$email
));
}
public static function forNonexistentUser(string $userId) : self
{
return new self(sprintf(
'User with the ID: %s does not exist',
$userId
));
}
}
class InvalidUserException extends DomainException
{
public static function forEmptyEmail() : self
{
return new self("User's email address must not be empty");
}
public static function forInvalidEmail(string $email) : self
{
return new self(sprintf(
'%s is not a valid email address',
$email
));
}
}
class UserNotFoundException extends RuntimeException
{
public static function forUserId(string $userId) : self
{
return new self(sprintf(
'User with the ID: %s does not exist',
$userId
));
}
}
namespace App\Domain\Exception;
interface ExceptionInterface
{
}
class UserNotFoundException extends \RuntimeException impements ExceptionInterface
{
public static function forUserId(string $userId) : self
{
return new self(
sprintf(
'User with the ID: %s does not exist',
$userId
)
);
}
}
use App\DBAL\Exception\ExceptionInterface as DBALException;
use App\Domain\Exception\ExceptionInterface as DomainException;
try {
//some code...
} catch (DBALException $dbalEx) {
//...
} catch (DomainException $domainEx) {
//...
} catch (\Exception $ex) {
//...
}
class UserNotFoundException extends RuntimeException
{
public static function forUserId(string $userId) : self
{
return new self(
sprintf(
'User with the ID: %s does not exist',
$userId
),
ErrorCodes::ERROR_USER_NOT_FOUND
);
}
}
use Whoops\Run;
use Whoops\Handler\PrettyPageHandler;
use Whoops\Handler\JsonResponseHandler;
$run = new Run();
$run->pushHandler(new PrettyPageHandler());
if (\Whoops\Util\Misc::isAjaxRequest()) {
$jsonHandler = new JsonResponseHandler();
$run->pushHandler($jsonHandler);
}
$run->register();
By Nikola Poša
Overview of widely accepted best practices for dealing with exceptional situations, writing and organizing exception classes, as well as error handling concepts. Guideline for writing custom exception classes, formatting exception messages, component-level exceptions technique, and much more. In a word - Exceptions cheat-sheet.
Web developer and software architect specializing in PHP based applications and web services.