Merge pull request #5 from lbryio/fix-unclean-exit

Fix unclean exit due to uncaught errors/exceptions
This commit is contained in:
Jack Robison 2019-02-11 12:28:28 -05:00 committed by GitHub
commit 5121e3b0c4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 31 additions and 11 deletions

View file

@ -155,8 +155,8 @@ class Gateway:
} }
@classmethod @classmethod
async def _discover_gateway(cls, lan_address: str, gateway_address: str, timeout: int=30, async def _discover_gateway(cls, lan_address: str, gateway_address: str, timeout: int = 30,
igd_args: OrderedDict=None, loop=None, unicast: bool=False): igd_args: OrderedDict = None, loop=None, unicast: bool = False):
ignored: set = set() ignored: set = set()
required_commands = [ required_commands = [
'AddPortMapping', 'AddPortMapping',
@ -181,7 +181,7 @@ class Gateway:
required for required in required_commands if required not in gateway._registered_commands required for required in required_commands if required not in gateway._registered_commands
] ]
log.debug("found gateway %s at %s, but it does not implement required soap commands: %s", log.debug("found gateway %s at %s, but it does not implement required soap commands: %s",
gateway.manufacturer_string, gateway.location, not_met) gateway.manufacturer_string, gateway.location, not_met)
ignored.add(datagram.location) ignored.add(datagram.location)
continue continue
else: else:
@ -196,19 +196,26 @@ class Gateway:
async def discover_gateway(cls, lan_address: str, gateway_address: str, timeout: int = 30, async def discover_gateway(cls, lan_address: str, gateway_address: str, timeout: int = 30,
igd_args: OrderedDict = None, loop=None, unicast: bool = None): igd_args: OrderedDict = None, loop=None, unicast: bool = None):
if unicast is not None: if unicast is not None:
return await cls._discover_gateway(lan_address, gateway_address, timeout, igd_args, loop) return await cls._discover_gateway(lan_address, gateway_address, timeout, igd_args, loop, unicast)
done, pending = await asyncio.wait([ done, pending = await asyncio.wait([
cls._discover_gateway( cls._discover_gateway(
lan_address, gateway_address, timeout, igd_args, loop, unicast=True lan_address, gateway_address, timeout, igd_args, loop, unicast=True
), ),
cls._discover_gateway( cls._discover_gateway(
lan_address, gateway_address, timeout, igd_args, loop, unicast=False lan_address, gateway_address, timeout, igd_args, loop, unicast=False
)], return_when=asyncio.tasks.FIRST_COMPLETED )
) ], return_when=asyncio.tasks.FIRST_COMPLETED)
for task in list(pending):
for task in pending:
task.cancel() task.cancel()
result = list(done)[0].result() for task in done:
return result try:
task.exception()
except asyncio.CancelledError:
pass
return list(done)[0].result()
async def discover_commands(self, loop=None): async def discover_commands(self, loop=None):
response, xml_bytes, get_err = await scpd_get(self.path.decode(), self.base_ip.decode(), self.port, loop=loop) response, xml_bytes, get_err = await scpd_get(self.path.decode(), self.base_ip.decode(), self.port, loop=loop)

View file

@ -394,7 +394,7 @@ class UPnP:
try: try:
result = fut.result() result = fut.result()
except UPnPError as err: except UPnPError as err:
print("aioupnp encountered an error:\n%s" % str(err)) print("aioupnp encountered an error: %s" % str(err))
return return
if isinstance(result, (list, tuple, dict)): if isinstance(result, (list, tuple, dict)):

View file

@ -85,7 +85,7 @@ class TestCLI(TestBase):
def test_m_search(self): def test_m_search(self):
actual_output = StringIO() actual_output = StringIO()
timeout_msg = "aioupnp encountered an error:\nM-SEARCH for 10.0.0.1:1900 timed out\n" timeout_msg = "aioupnp encountered an error: M-SEARCH for 10.0.0.1:1900 timed out\n"
with contextlib.redirect_stdout(actual_output): with contextlib.redirect_stdout(actual_output):
with mock_tcp_and_udp(self.loop, '10.0.0.1', tcp_replies=self.scpd_replies, udp_replies=self.udp_replies): with mock_tcp_and_udp(self.loop, '10.0.0.1', tcp_replies=self.scpd_replies, udp_replies=self.udp_replies):
main( main(

View file

@ -1,3 +1,6 @@
import asyncio
from aioupnp.fault import UPnPError
from tests import TestBase from tests import TestBase
from tests.mocks import mock_tcp_and_udp from tests.mocks import mock_tcp_and_udp
from collections import OrderedDict from collections import OrderedDict
@ -62,6 +65,16 @@ class TestDiscoverDLinkDIR890L(TestBase):
'GetExternalIPAddress': 'urn:schemas-upnp-org:service:WANIPConnection:1' 'GetExternalIPAddress': 'urn:schemas-upnp-org:service:WANIPConnection:1'
} }
async def test_discover_gateway(self):
with self.assertRaises(UPnPError) as e1:
with mock_tcp_and_udp(self.loop):
await Gateway.discover_gateway("10.0.0.2", "10.0.0.1", 2)
with self.assertRaises(UPnPError) as e2:
with mock_tcp_and_udp(self.loop):
await Gateway.discover_gateway("10.0.0.2", "10.0.0.1", 2, unicast=False)
self.assertEqual(str(e1.exception), "M-SEARCH for 10.0.0.1:1900 timed out")
self.assertEqual(str(e2.exception), "M-SEARCH for 10.0.0.1:1900 timed out")
async def test_discover_commands(self): async def test_discover_commands(self):
with mock_tcp_and_udp(self.loop, tcp_replies=self.replies): with mock_tcp_and_udp(self.loop, tcp_replies=self.replies):
gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address) gateway = Gateway(self.reply, self.m_search_args, self.client_address, self.gateway_address)