public function record(
        $callback,
        Arguments $arguments,
        SpyData $spy
    ): CallData {
        $originalArguments = $arguments->copy();

        $call = new CallData(
            $spy->nextIndex(),
            $this->eventFactory->createCalled($spy, $originalArguments)
        );
        $spy->addCall($call);

        $returnValue = null;
        $exception = null;

        try {
            $returnValue = $this->invoker->callWith($callback, $arguments);
        } catch (Throwable $exception) {
            // handled below
        }

        if ($exception) {
            $responseEvent = $this->eventFactory->createThrew($exception);
        } else {
            $responseEvent = $this->eventFactory->createReturned($returnValue);
        }

        $call->setResponseEvent($responseEvent);

        return $call;
    }