Separate protocol processing exceptions

- exceptions thrown by the state methods are separated from missing
  connections or states. This allows more accurate error reporting
This commit is contained in:
Peter Šurda 2018-02-19 21:27:38 +01:00
parent fde194f9b0
commit 1184b23223
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
2 changed files with 24 additions and 8 deletions

View File

@ -7,6 +7,12 @@ from debug import logger
from helper_threading import BusyError, nonBlocking from helper_threading import BusyError, nonBlocking
import state import state
class ProcessingError(Exception):
pass
class UnknownStateError(ProcessingError):
pass
class AdvancedDispatcher(asyncore.dispatcher): class AdvancedDispatcher(asyncore.dispatcher):
_buf_len = 131072 # 128kB _buf_len = 131072 # 128kB
@ -58,11 +64,13 @@ class AdvancedDispatcher(asyncore.dispatcher):
break break
if len(self.read_buf) < self.expectBytes: if len(self.read_buf) < self.expectBytes:
return False return False
if not getattr(self, "state_" + str(self.state))(): try:
cmd = getattr(self, "state_" + str(self.state))
except AttributeError:
logger.error("Unknown state %s", self.state, exc_info=True)
raise UnknownState(self.state)
if not cmd():
break break
except AttributeError:
logger.error("Unknown state %s", self.state, exc_info=True)
raise
except BusyError: except BusyError:
return False return False
return False return False

View File

@ -12,6 +12,7 @@ from helper_threading import StoppableThread
from inventory import Inventory from inventory import Inventory
from network.connectionpool import BMConnectionPool from network.connectionpool import BMConnectionPool
from network.bmproto import BMProto from network.bmproto import BMProto
from network.advanceddispatcher import UnknownStateError
from queues import receiveDataQueue from queues import receiveDataQueue
import protocol import protocol
import state import state
@ -40,14 +41,21 @@ class ReceiveQueueThread(threading.Thread, StoppableThread):
# or the connection is to be aborted # or the connection is to be aborted
try: try:
BMConnectionPool().getConnectionByAddr(dest).process() connection = BMConnectionPool().getConnectionByAddr(dest)
# KeyError = connection object not found # KeyError = connection object not found
# AttributeError = state isn't implemented except KeyError:
except (KeyError, AttributeError): receiveDataQueue.task_done()
continue
try:
connection.process()
# UnknownStateError = state isn't implemented
except (UnknownStateError):
pass pass
except socket.error as err: except socket.error as err:
if err.errno == errno.EBADF: if err.errno == errno.EBADF:
BMConnectionPool().getConnectionByAddr(dest).set_state("close", 0) connection.set_state("close", 0)
else: else:
logger.error("Socket error: %s", str(err)) logger.error("Socket error: %s", str(err))
except:
logger.error("Error processing", exc_info=True)
receiveDataQueue.task_done() receiveDataQueue.task_done()