/**
  * Handle a single RPC request.
  *
  * @todo Implement notifications: if $id is null call $this->service->publish instead of $this->service->call, and skip response
  * 
  * @param Request $request
  * @param array   $data
  *
  * @return \JsonSerializable
  */
 private function handle(Request $request, array $data)
 {
     $id = isset($data['id']) ? $data['id'] : null;
     if (!isset($data['jsonrpc'])) {
         return ErrorReply::makeInvalidRequest($id, 'Request does not seems to be valid JSON RPC request');
     }
     if ($data['jsonrpc'] !== '2.0') {
         return ErrorReply::makeInvalidRequest($id, 'JSON RPC version is not supported');
     }
     if (empty($data['method'])) {
         return ErrorReply::makeInvalidRequest($id, 'Method name is not defined or empty');
     }
     try {
         $reply = $this->service->call(new RequestMessage($data['method'], $this->fetchVersion($request), isset($data['params']) ? $data['params'] : [], $this->fetchHeaders($request)))->resolve($this->timeout);
         return new ResultReply($id, $reply->getValue());
     } catch (RequestNotSupportedException $e) {
         return ErrorReply::makeMethodNotFound($id, $e->getMessage());
     } catch (\Exception $e) {
         return ErrorReply::makeInternalError($id, $e->getMessage());
     }
 }
 public function testHandlingException()
 {
     $this->service->expects($this->once())->method('call')->willThrowException(new \Exception('Error'));
     $response = $this->controller->__invoke(new Request([], [], [], [], [], [], '{"jsonrpc": "2.0", "method": "test"}'));
     $this->assertJsonStringEqualsJsonString(json_encode(['jsonrpc' => '2.0', 'error' => ['code' => -32603, 'message' => 'Error'], 'id' => null]), $response->getContent());
 }