public function it_triggers_the_callback_on_failure_when_an_exception_is_raised_during_command_handling(Command $command, CommandCallback $callback, $handlerRegistry, CommandHandler $handler)
 {
     $handlerRegistry->findCommandHandlerFor($command)->willReturn($handler);
     $failureCause = new \Exception();
     $handler->handle($command)->willThrow($failureCause);
     $callback->onFailure($failureCause)->shouldBeCalledTimes(1);
     $callback->onSuccess(Argument::any())->shouldNotBeCalled();
     $this->shouldThrow($failureCause)->during('dispatch', [$command, $callback]);
 }
 /**
  * @param Command         $command
  * @param CommandCallback $callback
  *
  * @throws \Exception
  */
 public function dispatch(Command $command, CommandCallback $callback = null)
 {
     $handler = $this->handlerRegistry->findCommandHandlerFor($command);
     $this->unitOfWork->start();
     try {
         $result = $handler->handle($command);
         if (null !== $callback) {
             $callback->onSuccess($result);
         }
     } catch (\Exception $exception) {
         $this->unitOfWork->rollback($exception);
         if (null !== $callback) {
             $callback->onFailure($exception);
         }
         // Todo: remove this ?
         throw $exception;
     }
     $this->unitOfWork->commit();
 }
 /**
  * @param Command         $command
  * @param CommandCallback $callback
  *
  * @throws \Exception
  */
 public function dispatch(Command $command, CommandCallback $callback = null)
 {
     $command = $this->intercept($command);
     $handler = $this->handlerRegistry->findCommandHandlerFor($command);
     $this->unitOfWork->start();
     $interceptorChain = new DefaultInterceptorChain($command, $this->unitOfWork, $handler, ...$this->handlerInterceptors);
     try {
         $result = $interceptorChain->proceed();
         if (null !== $callback) {
             $callback->onSuccess($result);
         }
     } catch (\Exception $exception) {
         $this->unitOfWork->rollback($exception);
         if (null !== $callback) {
             $callback->onFailure($exception);
         }
         throw $exception;
     }
     $this->unitOfWork->commit();
     return $result;
 }