summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakeshi KOMIYA <i.tkomiya@gmail.com>2020-10-03 21:42:29 +0900
committerGitHub <noreply@github.com>2020-10-03 21:42:29 +0900
commit1eaa06844ef4a229ff0b2926708ba5727ab2cf53 (patch)
treea2736253509172e82c4d81a69e3bfc8fbda14bc8
parent1e2ccd8f0eca0870cf6f8fce6934e2da8eba9b72 (diff)
parent5ea8ee133dfac71e58d1d6fb8f6b38a7ba249a7c (diff)
downloadsphinx-git-1eaa06844ef4a229ff0b2926708ba5727ab2cf53.tar.gz
Merge pull request #8269 from francoisfreitag/raise-anchor
Fix #8268: make linkcheck report HTTP errors
-rw-r--r--CHANGES1
-rw-r--r--sphinx/builders/linkcheck.py1
-rw-r--r--tests/roots/test-linkcheck-localserver/conf.py2
-rw-r--r--tests/roots/test-linkcheck-localserver/index.rst1
-rw-r--r--tests/test_build_linkcheck.py36
5 files changed, 41 insertions, 0 deletions
diff --git a/CHANGES b/CHANGES
index 22876d43b..7013a6d01 100644
--- a/CHANGES
+++ b/CHANGES
@@ -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
--------
diff --git a/sphinx/builders/linkcheck.py b/sphinx/builders/linkcheck.py
index 9b54afc7c..1083e82ec 100644
--- a/sphinx/builders/linkcheck.py
+++ b/sphinx/builders/linkcheck.py
@@ -166,6 +166,7 @@ class CheckExternalLinksBuilder(Builder):
# 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:
diff --git a/tests/roots/test-linkcheck-localserver/conf.py b/tests/roots/test-linkcheck-localserver/conf.py
new file mode 100644
index 000000000..2ba1f85e8
--- /dev/null
+++ b/tests/roots/test-linkcheck-localserver/conf.py
@@ -0,0 +1,2 @@
+exclude_patterns = ['_build']
+linkcheck_anchors = True
diff --git a/tests/roots/test-linkcheck-localserver/index.rst b/tests/roots/test-linkcheck-localserver/index.rst
new file mode 100644
index 000000000..807fe964b
--- /dev/null
+++ b/tests/roots/test-linkcheck-localserver/index.rst
@@ -0,0 +1 @@
+`local server <http://localhost:7777/#anchor>`_
diff --git a/tests/test_build_linkcheck.py b/tests/test_build_linkcheck.py
index 7d85f10c5..a78587668 100644
--- a/tests/test_build_linkcheck.py
+++ b/tests/test_build_linkcheck.py
@@ -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
@@ -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,
@@ -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")