Improved error handling (OSError is now properly handled)
This commit is contained in:
parent
615865234d
commit
e28e8f51fd
1 changed files with 29 additions and 20 deletions
|
@ -3,13 +3,11 @@ import DataTypes
|
||||||
import Logging
|
import Logging
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
from Utils import capture_trace
|
||||||
import socket
|
import socket
|
||||||
import _thread
|
import _thread
|
||||||
|
|
||||||
def capture_trace():
|
|
||||||
exc_type, exc_value, exc_traceback = sys.exc_info()
|
|
||||||
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
|
||||||
|
|
||||||
class Server:
|
class Server:
|
||||||
def __init__(self, host_port_pair, debug=False):
|
def __init__(self, host_port_pair, debug=False):
|
||||||
|
@ -37,34 +35,45 @@ class Server:
|
||||||
self.sock.close()
|
self.sock.close()
|
||||||
|
|
||||||
def controller(self, sock, info, handler_args):
|
def controller(self, sock, info, handler_args):
|
||||||
sock = ESock(sock) if not self.debug else ESock(sock, debug=True)
|
sock = ESock(sock) if not self.debug else ESock(sock, debug=self.debug)
|
||||||
handler = self.handler(sock, info, **handler_args)
|
handler = self.handler(sock, info, **handler_args)
|
||||||
while 1:
|
while 1:
|
||||||
try:
|
try:
|
||||||
data, route = sock.recv()
|
data, route = sock.recv()
|
||||||
handler.handle(data, route)
|
handler.handle(data, route)
|
||||||
except (BrokenPipeError, ConnectionResetError, OSError) as e:
|
except (BrokenPipeError, ConnectionResetError, OSError) as e:
|
||||||
|
socket_related_error = True
|
||||||
|
if type(e) not in (BrokenPipeError, ConnectionResetError, OSError):
|
||||||
|
socket_related_error = False
|
||||||
if type(e) is OSError:
|
if type(e) is OSError:
|
||||||
if str(e) not in ("Connection closed", "Bad file descriptor"):
|
if str(e) not in ("Connection closed", "[Errno 9] Bad file descriptor"):
|
||||||
raise
|
socket_related_error = False
|
||||||
handler.finish()
|
if not socket_related_error:
|
||||||
if sock in self.socks:
|
self.print_trace(handler, sock)
|
||||||
del self.socks[self.socks.index(sock)]
|
self.attempt_graceful_close(handler, sock)
|
||||||
sock.close()
|
|
||||||
_thread.exit()
|
_thread.exit()
|
||||||
except Exception:
|
except Exception:
|
||||||
Logging.error("An unhandled exception forced the controller for '%s:%d' to terminate." % (sock.address, sock.port))
|
self.print_trace(handler, sock)
|
||||||
capture_trace()
|
self.attempt_graceful_close(handler, sock)
|
||||||
try:
|
|
||||||
handler.finish()
|
|
||||||
except Exception:
|
|
||||||
capture_trace()
|
|
||||||
if sock in self.socks:
|
|
||||||
del self.socks[self.socks.index(sock)]
|
|
||||||
sock.close()
|
|
||||||
_thread.exit()
|
_thread.exit()
|
||||||
|
|
||||||
|
|
||||||
|
def print_trace(self, handler, sock):
|
||||||
|
Logging.error("An unhandled exception forced the controller for '%s:%d' to terminate." % (sock.address, sock.port))
|
||||||
|
capture_trace()
|
||||||
|
|
||||||
|
|
||||||
|
def attempt_graceful_close(self, handler, sock):
|
||||||
|
try:
|
||||||
|
handler.finish()
|
||||||
|
except Exception:
|
||||||
|
self.print_trace(handler, sock)
|
||||||
|
finally:
|
||||||
|
if sock in self.socks:
|
||||||
|
del self.socks[self.socks.index(sock)]
|
||||||
|
sock.close()
|
||||||
|
|
||||||
|
|
||||||
class Handler:
|
class Handler:
|
||||||
def __init__(self, sock, info, **kwargs):
|
def __init__(self, sock, info, **kwargs):
|
||||||
self.sock = sock
|
self.sock = sock
|
||||||
|
|
Reference in a new issue