diff --git a/mercurial/hgweb/server.py b/mercurial/hgweb/server.py --- a/mercurial/hgweb/server.py +++ b/mercurial/hgweb/server.py @@ -81,6 +81,7 @@ class _httprequesthandler(BaseHTTPServer except Exception: self._start_response("500 Internal Server Error", []) self._write("Internal Server Error") + self._done() tb = "".join(traceback.format_exception(*sys.exc_info())) self.log_error("Exception happened during processing " "request '%s':\n%s", self.path, tb) diff --git a/tests/get-with-headers.py b/tests/get-with-headers.py --- a/tests/get-with-headers.py +++ b/tests/get-with-headers.py @@ -43,9 +43,8 @@ def request(host, path, show): print "%s: %s" % (h, response.getheader(h)) if not headeronly: print - if response.status != 500: - data = response.read() - sys.stdout.write(data) + data = response.read() + sys.stdout.write(data) if twice and response.getheader('ETag', None): tag = response.getheader('ETag') diff --git a/tests/hgweberror.py b/tests/hgweberror.py new file mode 100644 --- /dev/null +++ b/tests/hgweberror.py @@ -0,0 +1,17 @@ +# A dummy extension that installs an hgweb command that throws an Exception. + +from mercurial.hgweb import webcommands + +def raiseerror(web, req, tmpl): + '''Dummy web command that raises an uncaught Exception.''' + + # Simulate an error after partial response. + if 'partialresponse' in req.form: + req.respond(200, 'text/plain') + req.write('partial content\n') + + raise AttributeError('I am an uncaught error!') + +def extsetup(ui): + setattr(webcommands, 'raiseerror', raiseerror) + webcommands.__all__.append('raiseerror') diff --git a/tests/test-hgweb.t b/tests/test-hgweb.t --- a/tests/test-hgweb.t +++ b/tests/test-hgweb.t @@ -579,4 +579,30 @@ errors $ cat errors.log +Uncaught exceptions result in a logged error and canned HTTP response + + $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS + $ hg --config extensions.hgweberror=$TESTDIR/hgweberror.py serve -p $HGPORT -d --pid-file=hg.pid -A access.log -E errors.log + $ cat hg.pid >> $DAEMON_PIDS + + $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror' transfer-encoding content-type + 500 Internal Server Error + transfer-encoding: chunked + + Internal Server Error (no-eol) + [1] + + $ head -1 errors.log + .* Exception happened during processing request '/raiseerror': (re) + +Uncaught exception after partial content sent + + $ $TESTDIR/get-with-headers.py localhost:$HGPORT 'raiseerror?partialresponse=1' transfer-encoding content-type + 200 Script output follows + transfer-encoding: chunked + content-type: text/plain + + partial content + Internal Server Error (no-eol) + $ cd ..