Skip to content

Commit

Permalink
Fix sphinx-doc#8268: make linkcheck report HTTP errors
Browse files Browse the repository at this point in the history
  • Loading branch information
francoisfreitag committed Oct 3, 2020
1 parent 9175da4 commit 5ea8ee1
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Bugs fixed
* #8093: The highlight warning has wrong location in some builders (LaTeX,
singlehtml and so on)
* #8239: Failed to refer a token in productionlist if it is indented
* #8268: linkcheck: Report HTTP errors when ``linkcheck_anchors`` is ``True``

Testing
--------
Expand Down
1 change: 1 addition & 0 deletions sphinx/builders/linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ def check_uri() -> Tuple[str, str, int]:
# Read the whole document and see if #anchor exists
response = requests.get(req_url, stream=True, config=self.app.config,
auth=auth_info, **kwargs)
response.raise_for_status()
found = check_anchor(response, unquote(anchor))

if not found:
Expand Down
2 changes: 2 additions & 0 deletions tests/roots/test-linkcheck-localserver/conf.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
exclude_patterns = ['_build']
linkcheck_anchors = True
1 change: 1 addition & 0 deletions tests/roots/test-linkcheck-localserver/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
`local server <http://localhost:7777/#anchor>`_
36 changes: 36 additions & 0 deletions tests/test_build_linkcheck.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
:license: BSD, see LICENSE for details.
"""

import http.server
import json
import re
import threading
from unittest import mock
import pytest

Expand Down Expand Up @@ -106,6 +108,21 @@ def test_anchors_ignored(app, status, warning):
# expect all ok when excluding #top
assert not content

@pytest.mark.sphinx('linkcheck', testroot='linkcheck-localserver', freshenv=True)
def test_raises_for_invalid_status(app, status, warning):
server_thread = HttpServerThread(InternalServerErrorHandler, daemon=True)
server_thread.start()
try:
app.builder.build_all()
finally:
server_thread.terminate()
content = (app.outdir / 'output.txt').read_text()
assert content == (
"index.rst:1: [broken] http://localhost:7777/#anchor: "
"500 Server Error: Internal Server Error "
"for url: http://localhost:7777/\n"
)


@pytest.mark.sphinx(
'linkcheck', testroot='linkcheck', freshenv=True,
Expand Down Expand Up @@ -160,3 +177,22 @@ def test_linkcheck_request_headers(app, status, warning):
assert headers["X-Secret"] == "open sesami"
else:
assert headers["Accept"] == "text/html,application/xhtml+xml;q=0.9,*/*;q=0.8"


class HttpServerThread(threading.Thread):
def __init__(self, handler, *args, **kwargs):
super().__init__(*args, **kwargs)
self.server = http.server.HTTPServer(("localhost", 7777), handler)

def run(self):
self.server.serve_forever(poll_interval=0.01)

def terminate(self):
self.server.shutdown()
self.server.server_close()
self.join()


class InternalServerErrorHandler(http.server.BaseHTTPRequestHandler):
def do_GET(self):
self.send_error(500, "Internal Server Error")

0 comments on commit 5ea8ee1

Please sign in to comment.