public function initTransaction(CommandInterface $command) { $trans = new CommandTransaction($this, $command); // Throwing in the init event WILL NOT emit an error event. $command->getEmitter()->emit('init', new InitEvent($trans)); $trans->request = $this->serializeRequest($trans); if ($future = $command->getFuture()) { $trans->request->getConfig()->set('future', $future); } $trans->state = 'prepared'; $prep = new PreparedEvent($trans); try { $command->getEmitter()->emit('prepared', $prep); } catch (\Exception $e) { $trans->exception = $e; $trans->exception = $this->createCommandException($trans); } // If the command failed in the prepare event or was intercepted, then // emit the process event now and skip hooking up the request. if ($trans->exception || $prep->isPropagationStopped()) { $this->emitProcess($trans); return $trans; } $trans->state = 'executing'; // When a request completes, process the request at the command // layer. $trans->request->getEmitter()->on('end', function (EndEvent $e) use($trans) { $trans->response = $e->getResponse(); if ($trans->exception = $e->getException()) { $trans->exception = $this->createCommandException($trans); } $this->emitProcess($trans); }, RequestEvents::LATE); return $trans; }