We sometimes see rendering errors in the error page itself, which then
cause another attempt at rendering the error page. I'm not sure _exactly_
how the loop is occurring, but it looks something like this:
1. An error is raised in a view or middleware and is not caught by
application code
2. Django catches the error and calls the registered uncaught error
handler
3. Our handler tries to render an error page
4. The rendering code raises an error
5. GOTO 2 (until some sort of server limit is reached)
By catching all errors raised during error-page render and substituting in
a hardcoded string, we can reduce server resources, avoid logging massive
sequences of recursive stack traces, and still give the user *some*
indication that yes, there was a problem.
This should help address https://github.com/openedx/edx-platform/issues/35151
At least one of these rendering errors is known to be due to a translation
error. There's a separate issue for restoring translation quality so that
we avoid those issues in the future (https://github.com/openedx/openedx-translations/issues/549)
but in general we should catch all rendering errors, including unknown
ones.
Testing:
- In `lms/envs/devstack.py` change `DEBUG` to `False` to ensure that the
usual error page is displayed (rather than the debug error page).
- Add line `1/0` to the top of the `student_dashboard` function in
`common/djangoapps/student/views/dashboard.py` to make that view error.
- In `lms/templates/static_templates/server-error.html` replace
`static.get_platform_name()` with `None * 7` to make the error template
itself produce an error.
- Visit <http://localhost:18000/dashboard>.
Without the fix, the response takes 10 seconds and produces a 6 MB, 85k
line set of stack traces and the page displays "A server error occurred.
Please contact the administrator."
With the fix, the response takes less than a second and produces three
stack traces (one of which contains the error page's rendering error).
Some of the static_template_view tests use names to get the URLs for the
error pages for testing, so I added names and updated the test to match
the new names.
I also updated the `test_404` function because we're no longer rendering
the 404 page in a different way from the 500 page so the response
includes the correct response code and content type. This reduces the
number of differences between the 404 handler and the 500 handler.
We were adding paths for the error pages in two places so one of them
simply wasn't being used. The lms urls.py also covered the 429 wich the
static_templates_view urls.py did not cover. We don't need both and we
need the definition of the handlerNNN variables in urls.py to override
the default django error views so I'll leave just those.
I also made the `exception` parameter for the `render_404` function
optional by adding a default value. We don't use the exception when
rendering the 404 page but the exception argument is a part of the
default method signature for the function that `render_404` replaces so
I didn't want to remove it and cause issues when django tries to call
this function.
*pyupgrade on static_templates, staticbook and support apps
This reverts commit 1ec2e797a1.
* Apply suggestions from code review
Co-authored-by: Usama Sadiq <usama.sadiq@arbisoft.com>
See context here: https://django-ratelimit.readthedocs.io/en/latest/cookbook/429.html#context
For now we continue to fall back to django's default 403 handler for 403
but provide a new 429 template that we use for ratelimit exceptions.
This commit also updates a logistration test that relied on the old 403
behavior of django-ratelimit instead of the newly added 429 behavior.
* Generate common/djangoapps import shims for LMS
* Generate common/djangoapps import shims for Studio
* Stop appending project root to sys.path
* Stop appending common/djangoapps to sys.path
* Import from common.djangoapps.course_action_state instead of course_action_state
* Import from common.djangoapps.course_modes instead of course_modes
* Import from common.djangoapps.database_fixups instead of database_fixups
* Import from common.djangoapps.edxmako instead of edxmako
* Import from common.djangoapps.entitlements instead of entitlements
* Import from common.djangoapps.pipline_mako instead of pipeline_mako
* Import from common.djangoapps.static_replace instead of static_replace
* Import from common.djangoapps.student instead of student
* Import from common.djangoapps.terrain instead of terrain
* Import from common.djangoapps.third_party_auth instead of third_party_auth
* Import from common.djangoapps.track instead of track
* Import from common.djangoapps.util instead of util
* Import from common.djangoapps.xblock_django instead of xblock_django
* Add empty common/djangoapps/__init__.py to fix pytest collection
* Fix pylint formatting violations
* Exclude import_shims/ directory tree from linting
* Use full LMS imports paths in LMS settings and urls modules
* Use full LMS import paths in Studio settings and urls modules
* Import from lms.djangoapps.badges instead of badges
* Import from lms.djangoapps.branding instead of branding
* Import from lms.djangoapps.bulk_email instead of bulk_email
* Import from lms.djangoapps.bulk_enroll instead of bulk_enroll
* Import from lms.djangoapps.ccx instead of ccx
* Import from lms.djangoapps.course_api instead of course_api
* Import from lms.djangoapps.course_blocks instead of course_blocks
* Import from lms.djangoapps.course_wiki instead of course_wiki
* Import from lms.djangoapps.courseware instead of courseware
* Import from lms.djangoapps.dashboard instead of dashboard
* Import from lms.djangoapps.discussion import discussion
* Import from lms.djangoapps.email_marketing instead of email_marketing
* Import from lms.djangoapps.experiments instead of experiments
* Import from lms.djangoapps.gating instead of gating
* Import from lms.djangoapps.grades instead of grades
* Import from lms.djangoapps.instructor_analytics instead of instructor_analytics
* Import form lms.djangoapps.lms_xblock instead of lms_xblock
* Import from lms.djangoapps.lti_provider instead of lti_provider
* Import from lms.djangoapps.mobile_api instead of mobile_api
* Import from lms.djangoapps.rss_proxy instead of rss_proxy
* Import from lms.djangoapps.static_template_view instead of static_template_view
* Import from lms.djangoapps.survey instead of survey
* Import from lms.djangoapps.verify_student instead of verify_student
* Stop suppressing EdxPlatformDeprecatedImportWarnings
Stop showing hitting enterprise API when request is originated as result of 404 error.
fixed quality violations
Removed line break
add unit tests
Updated test docstring
1. Using the pageheader and pagecontent block names.
2. Setting SiteConfiguration settings for each individual html page.
Co-authored by: Tomasz Gargas <tomasz@opencraft.com>
It should help catch unicode encoding problems earlier.
This also updates python-saml dependency to a version that includes a
patch for unicode strings.
2. Add site configuration overrides to theming/helpers.py
3. Move microsite.get_value from theming/helpers to site_configuration/helpers
4. Move microsite_configuration.microsite.get_value usages to site_configuration.helpers.values
Feature flagged. Puts a checkbox in the iframe. The iframe uses an organization_full_name parameter forwarded from Drupal by the courseware views and POSTs an email_opt_in parameter to the student views, preserving it on 403.