Skip to content

Instantly share code, notes, and snippets.

@dadamssg
Last active August 29, 2015 14:16
Show Gist options
  • Save dadamssg/dcd322da853d41cfdfb8 to your computer and use it in GitHub Desktop.
Save dadamssg/dcd322da853d41cfdfb8 to your computer and use it in GitHub Desktop.

Start throwing "not found" exceptions in your repositories

99% of the time you're going to want to bail if you're expecting to find an entity by a specific key. Having code like the two private methods in the old code below in every single one of your handlers is crazy and not DRY.

I think the idea of "only throw exceptions when something exceptional happens" is too generic and doesn't take context into consideration.

A repository's only job is to find entities. If you give it a key and it can't find it, i think that's exceptional(in the context of the repository).

If it actually is expected in your client code it's not a big deal, catch the EntityNotFoundException and carry on.

This also unifies the types of exceptions thrown. It is entirely possible some handlers could be throwing a EntityNotFoundException while your partner developer is throwing a ValidationException. Encapsulate that in the repository.

<?php

class AddPersonCommandHandler
{
	private $categories;

	private $people;

	public function __construct(CategoryRepsoitory $categories, PersonRepository $people)
	{
		$this->categories = $categories;
		$this->people = $people;
	}

	public function handle(AddPersonCommand $command)
	{
		$category = $this->findCategory($command->getCategoryId()));
		$referrer = $this->findPerson($command->getReferrerId());

		$person = new Person(
			$command->getName(),
			$category,
			$referrer
		);

		$this->people->add($person);
	}

	private function findCategory($id)
	{
		if (null === $category = $this->categories->find($id)) {
			throw new EntityNotFoundException("Cateogry not found.");
		}

		return $category;
	}

	private function findPerson($id)
	{
		if (null === $person = $this->people->find($id)) {
			throw new EntityNotFoundException("Person not found.");
		}

		return $person;		
	}
}

Becomes

<?php

class AddPersonCommandHandler
{
	private $categories;

	private $people;

	public function __construct(CategoryRepsoitory $categories, PersonRepository $people)
	{
		$this->categories = $categories;
		$this->people = $people;
	}

	public function handle(AddPersonCommand $command)
	{
		$category = $this->categories->find($command->getCategoryId());
		$referrer = $this->people->find($command->getReferrerId());

		$person = new Person(
			$command->getName(),
			$category,
			$referrer
		);

		$this->people->add($person);
	}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment