Bug 1321517 - Propagate exception from server subprocess and re-raise. r?whimboo
When an exception occurs during startup of ServerProxy it is logged
to stdout and the subprocess terminates. The exception is however not
propagated/communicated to the parent process so it can take action on it.
This patch returns the exception via the BlockingChannel pipe and
re-raises it in the parent process. This will cause serve.py to
exit if one of the HTTPD servers fails to start. This fixes the
problem reported in
bug 1321517, where the HTTP server lives on when
the HTTPS server fails to start due to a missing certificate or key file.
--- a/testing/marionette/harness/marionette_harness/runner/serve.py
+++ b/testing/marionette/harness/marionette_harness/runner/serve.py
@@ -66,20 +66,21 @@ class ServerProxy(multiprocessing.Proces
def __init__(self, channel, init_func, *init_args, **init_kwargs):
multiprocessing.Process.__init__(self)
BlockingChannel.__init__(self, channel)
self.init_func = init_func
self.init_args = init_args
self.init_kwargs = init_kwargs
def run(self):
- server = self.init_func(*self.init_args, **self.init_kwargs)
- server.start(block=False)
+ try:
+ server = self.init_func(*self.init_args, **self.init_kwargs)
+ server.start(block=False)
+ self.send(("ok", ()))
- try:
while True:
# ["func", ("arg", ...)]
# ["prop", ()]
sattr, fargs = self.recv()
attr = getattr(server, sattr)
# apply fargs to attr if it is a function
if callable(attr):
@@ -89,16 +90,19 @@ class ServerProxy(multiprocessing.Proces
else:
rv = attr
self.send(rv)
if sattr == "stop":
return
+ except Exception as e:
+ self.send(("stop", e))
+
except KeyboardInterrupt:
server.stop()
class ServerProc(BlockingChannel):
def __init__(self, init_func):
self._init_func = init_func
@@ -108,16 +112,20 @@ class ServerProc(BlockingChannel):
BlockingChannel.__init__(self, parent_chan)
def start(self, doc_root, ssl_config, **kwargs):
self.proc = ServerProxy(
self.child_chan, self._init_func, doc_root, ssl_config, **kwargs)
self.proc.daemon = True
self.proc.start()
+ res, exc = self.recv()
+ if res == "stop":
+ raise exc
+
def get_url(self, url):
return self.call("get_url", (url,))
@property
def doc_root(self):
return self.call("doc_root", ())
def stop(self):