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
import state
class ProcessingError(Exception):
pass
class UnknownStateError(ProcessingError):
pass
class AdvancedDispatcher(asyncore.dispatcher):
_buf_len = 131072 # 128kB
@ -58,11 +64,13 @@ class AdvancedDispatcher(asyncore.dispatcher):
break
if len(self.read_buf) < self.expectBytes:
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
except AttributeError:
logger.error("Unknown state %s", self.state, exc_info=True)
raise
except BusyError:
return False
return False

View File

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