docs: def handle_single_request(self, request_object):
          """
          Handles a single request object and returns the correct result as follows:
  
          - A valid response object if it is a regular request (with ID)
          - ``None`` if it was a notification (if None is returned, a response object with
            "received" body was already sent to the client.
  
          :param request_object: A :py:class:`gemstone.core.structs.JsonRpcRequest` object
                                 representing a Request object
          :return: A :py:class:`gemstone.core.structs.JsonRpcResponse` object representing a
                   Response object or None if no response is expected (it was a notification)
  
          """
          # don't handle responses?
          if isinstance(request_object, JsonRpcResponse):
              return request_object
  
          error = None
          result = None
          id_ = request_object.id
  
          # validate method name
          if request_object.method not in self.methods:
              resp = GenericResponse.METHOD_NOT_FOUND
              resp.id = id_
              return resp
  
          # check for private access
          method = self.methods[request_object.method]
  
          if isinstance(request_object.params, (list, tuple)):
              self.call_method_from_all_plugins("on_method_call", request_object)
          else:
              self.call_method_from_all_plugins("on_method_call", request_object)
  
          if self._method_is_private(method):
              if not self.get_current_user():
                  resp = GenericResponse.ACCESS_DENIED
                  resp.id = id_
                  return resp
  
          method = self.prepare_method_call(method, request_object.params)
  
          # before request hook
          _method_duration = time.time()
  
          try:
              result = yield self.call_method(method)
          except Exception as e:
              # catch all exceptions generated by method
              # and handle in a special manner only the TypeError
              if isinstance(e, TypeError):
                  # TODO: find a proper way to check that the function got the wrong
                  # parameters (with **kwargs)
                  if "got an unexpected keyword argument" in e.args[0]:
                      resp = GenericResponse.INVALID_PARAMS
                      resp.id = id_
                      return resp
                  # TODO: find a proper way to check that the function got the wrong
                  # parameters (with *args)
                  elif "takes" in e.args[0] and "positional argument" in e.args[0] and "were given" in \
                          e.args[0]:
                      resp = GenericResponse.INVALID_PARAMS
                      resp.id = id_
                      return resp
                  elif "missing" in e.args[0] and "required positional argument" in e.args[0]:
                      resp = GenericResponse.INVALID_PARAMS
                      resp.id = id_
                      return resp
              # generic handling for any exception (even TypeError) that
              # is not generated because of bad parameters
  
              self.call_method_from_all_plugins("on_internal_error", e)
  
              err = GenericResponse.INTERNAL_ERROR
              err.id = id_
              err.error["data"] = {
                  "class": type(e).__name__,
                  "info": str(e)
              }
              return err
  
          to_return_resp = JsonRpcResponse(result=result, error=error, id=id_)
  
          return to_return_resp