code: def on_error_close(logger):
      
      
      def make_wrapper(func):
          
          @functools.wraps(func)
          def wrapper(self, *args, **kwargs):
              
              d = defer.maybeDeferred(func, self, *args, **kwargs)
              def on_error(err):
                  logger("Unhandled failure in %r:%s" % (func, err. getTraceback()))
                  
                  if hasattr(self, "transport"):
                      if hasattr(self.transport, "abortConnection"):
                          self.transport.abortConnection()
                      elif hasattr(self.transport, "loseConnection"):
                          self.transport.loseConnection()
              d.addErrback(on_error)
              
          return wrapper
      return make_wrapper
docs: Decorator for callback methods that implement `IProtocol`. 
      
      Any uncaught exception is logged and the connection is closed
      forcefully.
      
      Usage::
          import logger
          logger = logging.getLogger(__name__)
          
          class MyProtocol(Protocol):
            @on_error_close(logger.error)
            def connectionMade():
                ...
      
      The argument passed to `on_error_close` will be invoked with a
      string message.
      
      The motivation behind this decorator is as follows:
      
      Due to bugs it sometimes happens that exceptions are thrown out out
      callback methods in protocols. Twisted ignores them, at best they
      are logged. This is always a bug, as errors should be handled in the
      callback and not let to continue up the call stack. As such, the 
      behaviour after this occured is typically not well defined and 
      unpredictable. 
      
      A well made protocol implementation can handle unexpected connection
      losses as they may occur at any time in a real world environment.
      
      By closing the connection, there is a certain chance
      that we enter a code path that can recover, or at least gracefully
      cleanup. 
      
      In my experience, this often means that unit-tests fail with a more
      useful error message. Without it, I sometimes get the case that a
      unit-test (or even the final application) just blocks forever
      with no information on what is going wrong.