Skip to content

Contextualize 404 page #9657

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 97 commits into from
Apr 26, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
fd380a5
WIP: Adds context to 404 page
benjaoming Oct 11, 2022
ad1cb2f
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Oct 12, 2022
aca278d
WIP: Adds a test 404 page
benjaoming Oct 12, 2022
7f86767
Contextualization gives us 3 interesting scenarios for the 404 page
benjaoming Oct 12, 2022
31ec5f5
404 handler: Receive exception keyword
benjaoming Oct 12, 2022
8cbff08
Improve contextualized messages, not ready for review, needs further …
benjaoming Oct 27, 2022
bc73398
Remove search form, that was a bad idea, since it will only work on s…
benjaoming Nov 1, 2022
a8573f9
Early work on an approach that uses a custom Http404 exception to sav…
benjaoming Nov 2, 2022
8bd53b6
Refactor error templates to separate contextualized handling + some t…
benjaoming Nov 3, 2022
7d1c69a
Apply new exceptions in some of the cases
benjaoming Nov 4, 2022
a30fa3c
Update readthedocs/proxito/exceptions.py
benjaoming Nov 7, 2022
c550ade
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Nov 23, 2022
0ef9c4d
Merge branch 'contextualize-404' of github.com:benjaoming/readthedocs…
benjaoming Nov 23, 2022
c505544
Refactor unresolver
stsewd Feb 16, 2023
d2eadec
Merge branch 'main' into refactor-unresolver
stsewd Feb 16, 2023
14bdbd2
Move external version checks inside unresolver
stsewd Feb 21, 2023
b807b2d
Merge branch 'main' into refactor-unresolver
stsewd Feb 21, 2023
b5006dc
Merge branch 'main' into refactor-unresolver
stsewd Feb 21, 2023
34d0cea
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Feb 22, 2023
dd43631
!fixup 8cbff084845a9a7ad0fd660f96be8bab245ec171
benjaoming Feb 22, 2023
0c07025
Update link to Custom 404 docs, remove rediraffe from tips
benjaoming Feb 22, 2023
9367e9e
Apply suggestions from code review
benjaoming Feb 22, 2023
d38491e
Raise custom 404 if subproject isn't found
benjaoming Feb 22, 2023
33f685b
Merge branch 'contextualize-404' of github.com:benjaoming/readthedocs…
benjaoming Feb 22, 2023
7f6f1b7
WIP: Conclude structure of exception classes and templates, needs mor…
benjaoming Feb 22, 2023
36b9f02
Updates from review
stsewd Feb 22, 2023
a4dee70
Reuse 404 view between proxito and general app, remove debug logging
benjaoming Feb 23, 2023
797e96b
Removes log.debug in views.serve
benjaoming Feb 23, 2023
8d38b8f
More work on text copy, fix bugs, raise ProxitoProjectVersionHttp404 …
benjaoming Feb 23, 2023
b60a109
Contextualize when subprojects aren't found. The disadvantages of the…
benjaoming Feb 23, 2023
b557590
Clean up
benjaoming Feb 23, 2023
3f7f2fd
Add project:slug search scope when pages aren't found
benjaoming Feb 23, 2023
63e64c2
clean up
benjaoming Feb 23, 2023
18823ba
Missed some linting there
benjaoming Feb 23, 2023
6dfde4c
fix pylint errors
benjaoming Feb 23, 2023
47338e9
Merge branch 'main' into refactor-unresolver
stsewd Feb 27, 2023
38496bc
Proxito: use unresolved in 404 handler
stsewd Feb 27, 2023
9fabc3d
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Feb 28, 2023
bece466
Don't use request.path as the "not found" path for proxito 404 except…
benjaoming Feb 28, 2023
46496df
Merge branch 'main' into refactor-unresolver
stsewd Feb 28, 2023
69f4886
Updates from review
stsewd Feb 28, 2023
b25608a
Merge remote-tracking branch 'upstream/use-proxito-v2-in-404-handler'…
benjaoming Mar 1, 2023
2184112
Missing imports
benjaoming Mar 1, 2023
ce28e12
Linting: Too many blank lines
benjaoming Mar 1, 2023
a9e7b09
Merge branch 'use-proxito-v2-in-404-handler' into contextualize-404
benjaoming Mar 1, 2023
7e12e2e
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Mar 1, 2023
3c8b76b
Merge branch 'main' of github.com:readthedocs/readthedocs.org into us…
benjaoming Mar 1, 2023
29a560c
Merge branch 'refactor-unresolver' of github.com:readthedocs/readthed…
benjaoming Mar 1, 2023
01f8cee
Add exception type for new 404 translation pages
benjaoming Mar 1, 2023
3085d95
Merge branch 'main' into use-proxito-v2-in-404-handler
stsewd Mar 2, 2023
05384be
Remove duplicated imports
stsewd Mar 2, 2023
7af491a
Black
stsewd Mar 2, 2023
86f67b2
Fix exc
stsewd Mar 2, 2023
2d92061
Update tests
stsewd Mar 2, 2023
f5b2db0
Merge branch 'main' into use-proxito-v2-in-404-handler
stsewd Mar 2, 2023
c017503
Move check to new implementation only
stsewd Mar 2, 2023
4c15d16
Merge branch 'use-proxito-v2-in-404-handler' of github.com:readthedoc…
benjaoming Mar 3, 2023
b5d96f4
Remove double error message for project 404s
benjaoming Mar 3, 2023
a36eb90
Add missing kwarg proxito_path for subproject 404 exception
benjaoming Mar 3, 2023
be22848
Updates from review
stsewd Mar 7, 2023
7e02a55
Merge branch 'use-proxito-v2-in-404-handler' of github.com:readthedoc…
benjaoming Mar 7, 2023
e3ff836
Add a new 404 exception class and targeted template for missing proje…
benjaoming Mar 7, 2023
03bbc6d
Updates from review
stsewd Mar 7, 2023
5ae6b6d
Merge branch 'use-proxito-v2-in-404-handler' of github.com:readthedoc…
benjaoming Mar 8, 2023
af07796
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Mar 8, 2023
d597b09
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Apr 11, 2023
b98dd0b
WIP: Simplify contextualized 404 messages into a set of exceptions. T…
benjaoming Apr 11, 2023
9a366bb
Revert changes on old proxito decorators implementation
benjaoming Apr 11, 2023
651161e
WIP: refactor
benjaoming Apr 12, 2023
3b7f4c0
Remove custom HTTP responses from most old proxito code, include CNAM…
benjaoming Apr 12, 2023
7c0c00c
Remove more changes to old proxito code
benjaoming Apr 12, 2023
93d7c48
Remove more old proxito implementation changes
benjaoming Apr 12, 2023
a1361d4
Use PRODUCTION_DOMAIN for search form action
benjaoming Apr 12, 2023
d20187c
Remove custom 404 handler from general app, have only that logic in p…
benjaoming Apr 12, 2023
b0e8db4
Remove a couple of additional unused patterns
benjaoming Apr 12, 2023
f0747c5
Comment accuracy update
benjaoming Apr 12, 2023
883aa50
Update another comment
benjaoming Apr 12, 2023
e70cec4
Revert DEBUG=False
benjaoming Apr 12, 2023
f195419
Move exceptions from core to proxito + use "path" from 404 serve view…
benjaoming Apr 12, 2023
62df795
Rename a few things
benjaoming Apr 12, 2023
11d099a
Removed unused kwarg
benjaoming Apr 12, 2023
2fa8a52
Update test cases to check for expected 404 exception and HTTP status
benjaoming Apr 12, 2023
92abfb9
Adds a test case variant to check the exception handling stack
benjaoming Apr 12, 2023
084ccc7
Apply suggestions from @stsewd code review
benjaoming Apr 19, 2023
607c735
use pgettext with context for 404 subjects
benjaoming Apr 19, 2023
344a845
change kwarg name, use some explicit kwargs
benjaoming Apr 19, 2023
6156040
Fix imports to be absolute
benjaoming Apr 19, 2023
9799f7e
Remove h3 from search bar when included with a search term
benjaoming Apr 19, 2023
239a0af
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Apr 19, 2023
81e46a9
explicitly require certain exception arguments, trim the ones we're n…
benjaoming Apr 20, 2023
d73d397
Apply suggestions from @stsewd code review
benjaoming Apr 26, 2023
18b5788
Remove |default filter and assume a value exists
benjaoming Apr 26, 2023
8945bff
Update readthedocs/templates/errors/404/include_tips.html
benjaoming Apr 26, 2023
a4816e4
Merge branch 'contextualize-404' of github.com:benjaoming/readthedocs…
benjaoming Apr 26, 2023
5e9017e
Add more context for translators of not_found_subject
benjaoming Apr 26, 2023
f5cf9d9
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Apr 26, 2023
8cd0404
Merge branch 'main' of github.com:readthedocs/readthedocs.org into co…
benjaoming Apr 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 13 additions & 5 deletions readthedocs/core/views/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,17 +48,25 @@ def get_context_data(self, **kwargs):
return context


def server_error_404(request, template_name="404.html", exception=None):
def server_error_404(
request, template_name="errors/404/community.html", exception=None
):
"""A simple 404 handler."""
# This property is set by ProxitoHttp404. We could also have a look at the
# subproject_slug

project_slug = getattr(exception, "project_slug", None)
log.debug(exception)
project = getattr(exception, "project", None)
log.debug(
"404 page detected a project slug in request.",
project_slug=project_slug,
)
subproject_slug = getattr(exception, "subproject_slug", None)

if subproject_slug:
template_name = "errors/404/no_subproject.html"
elif project:
template_name = "errors/404/no_project_page.html"
elif project_slug:
template_name = "errors/404/no_project.html"

r = render(
request,
template_name,
Expand Down
47 changes: 47 additions & 0 deletions readthedocs/proxito/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,54 @@
"""
This module contains exceptions that may be raised in the proxito application
but are handled elsewhere in the Django project.

--------------
404 exceptions
--------------

Because an Http404 can be raised anywhere in the code,
we want to add more context for targeted error handling and user-facing communication
"""
from django.http.response import Http404


class ProxitoHttp404(Http404):
"""
General error class for proxity 404s
"""

def __init__(self, message):
super().__init__(message)


class ProxitoProjectHttp404(ProxitoHttp404):
"""
Raised if a project was not found
"""

def __init__(self, message, project_slug=None):
self.project_slug = project_slug
super().__init__(message)


class ProxitoSubProjectHttp404(ProxitoProjectHttp404):
"""
Raised if a sub-project was not found
"""
def __init__(self, message, project_slug=None, project=None, subproject_slug=None):
self.project_slug = project_slug
self.project = project
self.subproject_slug = subproject_slug
super().__init__(message)


class ProxitoProjectPageHttp404(ProxitoHttp404):
"""
Raised if a page inside an existing project was not found

Note: The containing project can be both a project or a subproject inside another project
"""

def __init__(self, message, project_slug=None, project=None, subproject_slug=None):
self.project_slug = project_slug
self.project = project
Expand Down
11 changes: 1 addition & 10 deletions readthedocs/templates/401.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
{% extends "base.html" %}
{% extends "errors/base.html" %}
{% load core_tags %}
{% load i18n %}

{% block title %}
{% trans "Maze Found" %}
{% endblock %}

{% block header-wrapper %}
{% include "error_header.html" %}
{% endblock %}

{% block notify %}{% endblock %}

{# Hide the language select form so we don't set a CSRF cookie #}
{% block language-select-form %}{% endblock %}

{% block content %}
<h3>Permission Denied</h3>
<p>
Expand Down
86 changes: 2 additions & 84 deletions readthedocs/templates/404.html
Original file line number Diff line number Diff line change
@@ -1,84 +1,2 @@
{% extends "base.html" %}
{% load core_tags %}
{% load i18n %}

{% block title %}
{% trans "404 - Maze Found" %}
{% endblock %}

{% block header-wrapper %}
{% include "error_header.html" %}
{% endblock %}

{% block notify %}{% endblock %}

{# Hide the language select form so we don't set a CSRF cookie #}
{% block language-select-form %}{% endblock %}

{% block content %}

<h1>{% trans "404 - page not found" %}</h1>

{% if project %}

{# project exists #}

<p>
{% blocktrans with project_slug=project.slug request_path=request.path %}You are browsing the documentation of "{{ project_slug }}". The page you are looking for at <code>{{ request.path }}</code> was not found.{% endblocktrans %}
</p>

<p>
{% blocktrans %}Documentation changes over time. Pages are moved around. You can try to navigate to <a href="/">the index page</a> of the project and use its navigation or search function to find a similar page.{% endblocktrans %}</p>

<h3>{% trans "Are you the project owner?" %}</h3>

<p>{% trans "Here are some tips to address 404 errors:" %}</p>

<ul>
<li>{% trans "Use custom 404 pages:" %} <a href="https://docs.readthedocs.io/en/latest/hosting.html#custom-not-found-404-pages">{% trans "Read more" %}»</a></li>
<li>{% trans "Create redirects when you move contents:" %} <a href="https://docs.readthedocs.io/en/stable/user-defined-redirects.html">{% trans "Read more" %}»</a></li>
<li>{% trans "Use rediraffe to manage redirects in Sphinx:" %} <a href="https://pypi.org/project/sphinxext-rediraffe/">{% trans "Read more" %}»</a></li>
</ul>

{% elif "_proxito_404_" in request.path %}

{# we are looking at a 404 generated by proxito, we then know that the project itself doesn't exist or hasn't been built #}

<p>
{% blocktrans with project_slug=project_slug %}The project "{{ project_slug }}" that you are looking for either does not exist, has been deleted or does not yet have any valid builds.{% endblocktrans %}
</p>

{% else %}

<p>{% trans "You have encountered a 404 on Read the Docs. You are either looking for a page that does not exist or a project that has been removed." %}</p>

<p>{% trans "If you believe this is a technical error, please contact our support:" %} <a href="{% url 'support' %}">{% trans "Go to support" %}»</a></p>

{% endif %}

<pre style="line-height: 1.25; white-space: pre;">

\ SORRY /
\ /
\ This page does /
] not exist yet. [ ,'|
] [ / |
]___ ___[ ,' |
] ]\ /[ [ |: |
] ] \ / [ [ |: |
] ] ] [ [ [ |: |
] ] ]__ __[ [ [ |: |
] ] ] ]\ _ /[ [ [ [ |: |
] ] ] ] (#) [ [ [ [ :===='
] ] ]_].nHn.[_[ [ [
] ] ] HHHHH. [ [ [
] ] / `HH("N \ [ [
]__]/ HHH " \[__[
] NNN [
] N/" [
] N H [
/ N \
/ q, \
/ \
</pre>
{% endblock %}
{% extends "errors/404/base.html" %}
{# this is a deprecated template, will be removed. Please use one of the targeted 404s in templates/404/ #}
11 changes: 1 addition & 10 deletions readthedocs/templates/429.html
Original file line number Diff line number Diff line change
@@ -1,20 +1,11 @@
{% extends "base.html" %}
{% extends "errors/base.html" %}
{% load core_tags %}
{% load i18n %}

{% block title %}
{% trans "Too many requests" %}
{% endblock %}

{% block header-wrapper %}
{% include "error_header.html" %}
{% endblock %}

{% block notify %}{% endblock %}

{# Hide the language select form so we don't set a CSRF cookie #}
{% block language-select-form %}{% endblock %}

{% block content %}
<pre style="line-height: 1.25; white-space: pre;">
.--~~,__
Expand Down
11 changes: 1 addition & 10 deletions readthedocs/templates/500.html
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
{% extends "base.html" %}
{% extends "errors/base.html" %}
{% load i18n %}

{% block title %}
{% trans "Server Error" %}
{% endblock %}

{% block header-wrapper %}
{% include "error_header.html" %}
{% endblock %}

{% block notify %}{% endblock %}

{# Hide the language select form so we don't set a CSRF cookie #}
{% block language-select-form %}{% endblock %}

{% block content %}
<pre style="line-height: 1.25; white-space: pre;">
.
Expand Down
1 change: 1 addition & 0 deletions readthedocs/templates/error_header.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{% load i18n %}
{# this template is deprecated, please extend from errors/base.html #}

<div id="rtfd-header">
<div class="wrapper">
Expand Down
50 changes: 50 additions & 0 deletions readthedocs/templates/errors/404/base.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
{% extends "errors/base.html" %}
{% load core_tags %}
{% load i18n %}

{% block title %}
{% trans "404 - Maze Found" %}
{% endblock %}

{% block content %}

<h1>{% trans "404 - page not found" %}</h1>

{% block 404_error_message %}

{% endblock %}

{% if project %}

{% elif "_proxito_404_" in request.path %}

{% else %}

{% endif %}

<pre style="line-height: 1.25; white-space: pre;">

\ SORRY /
\ /
\ This page does /
] not exist yet. [ ,'|
] [ / |
]___ ___[ ,' |
] ]\ /[ [ |: |
] ] \ / [ [ |: |
] ] ] [ [ [ |: |
] ] ]__ __[ [ [ |: |
] ] ] ]\ _ /[ [ [ [ |: |
] ] ] ] (#) [ [ [ [ :===='
] ] ]_].nHn.[_[ [ [
] ] ] HHHHH. [ [ [
] ] / `HH("N \ [ [
]__]/ HHH " \[__[
] NNN [
] N/" [
] N H [
/ N \
/ q, \
/ \
</pre>
{% endblock %}
12 changes: 12 additions & 0 deletions readthedocs/templates/errors/404/community.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{% extends "errors/404/base.html" %}
{% load i18n %}

{# something on readthedocs.org does not exist - this 404 is not intended for projects #}

{% block 404_error_message %}

<p>{% trans "You have encountered a 404 on Read the Docs. You are either looking for a page that does not exist or a project that has been removed." %}</p>

<p>{% trans "If you believe this is a technical error, please contact our support:" %} <a href="{% url 'support' %}">{% trans "Go to support" %}»</a></p>

{% endblock %}
11 changes: 11 additions & 0 deletions readthedocs/templates/errors/404/include_tips.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{% load i18n %}

<h3>{% trans "Are you the project owner?" %}</h3>

<p>{% trans "Here are some tips to address 404 errors:" %}</p>

<ul>
<li>{% trans "Use custom 404 pages:" %} <a href="https://docs.readthedocs.io/en/latest/hosting.html#custom-not-found-404-pages">{% trans "Read more" %}»</a></li>
<li>{% trans "Create redirects when you move contents:" %} <a href="https://docs.readthedocs.io/en/stable/user-defined-redirects.html">{% trans "Read more" %}»</a></li>
<li>{% trans "Use rediraffe to manage redirects in Sphinx:" %} <a href="https://pypi.org/project/sphinxext-rediraffe/">{% trans "Read more" %}»</a></li>
</ul>
16 changes: 16 additions & 0 deletions readthedocs/templates/errors/404/no_project.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends "errors/404/base.html" %}
{% load i18n %}

{# visiting a slug or subdomain that doesn't match the intended project #}

{% block 404_error_message %}

{# we are looking at a 404 generated by proxito, we then know that the project itself doesn't exist or hasn't been built #}

<p>
{% blocktrans trimmed with project_slug=project_slug %}
The project "{{ project_slug }}" that you are looking for either does not exist, has been deleted or does not yet have any valid builds.
{% endblocktrans %}
</p>

{% endblock %}
22 changes: 22 additions & 0 deletions readthedocs/templates/errors/404/no_project_page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% extends "errors/404/base.html" %}
{% load i18n %}

{# project exists but page doesn't #}

{% block 404_error_message %}

<p>
{% blocktrans trimmed with project_slug=project.slug request_path=request.path %}
You are browsing the documentation of "{{ project_slug }}". The page you are looking for at <code>{{ request.path }}</code> was not found.
{% endblocktrans %}
</p>

<p>
{% blocktrans trimmed %}
Documentation changes over time. Pages are moved around. You can try to navigate to <a href="/">the index page</a> of the project and use its navigation or search function to find a similar page.
{% endblocktrans %}
</p>

{% include "errors/404/include_tips.html" %}

{% endblock %}
22 changes: 22 additions & 0 deletions readthedocs/templates/errors/404/no_subproject.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% extends "errors/404/base.html" %}
{% load i18n %}

{# project exists but page doesn't #}

{% block 404_error_message %}

<p>
{% blocktrans trimmed with project_slug=project.slug request_path=request.path %}
You are browsing the documentation of "{{ project_slug }}". The page you are looking for at <code>{{ request.path }}</code> was not found.
{% endblocktrans %}
</p>

<p>
{% blocktrans trimmed %}
Documentation changes over time. Pages are moved around. You can try to navigate to <a href="/">the index page</a> of the project and use its navigation or search function to find a similar page.
{% endblocktrans %}
</p>

{% include "errors/404/include_tips.html" %}

{% endblock %}
Loading