Skip to content
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

StaticHTMLRenderer cannot handle ValidationError #9209

Open
2 of 3 tasks
sevdog opened this issue Jan 4, 2024 · 2 comments · May be fixed by #9212
Open
2 of 3 tasks

StaticHTMLRenderer cannot handle ValidationError #9209

sevdog opened this issue Jan 4, 2024 · 2 comments · May be fixed by #9212

Comments

@sevdog
Copy link
Contributor

sevdog commented Jan 4, 2024

Checklist

  • Raised initially as discussion #...
  • This cannot be dealt with as a third party library. (We prefer new functionality to be in the form of third party libraries where possible.)
  • I have reduced the issue to the simplest possible case.

Description

If any ValidationError is raised in a view which is going to use StaticHTMLRenderer then it will cause an error resulting in an Internal-Server-Error because the base class TemplateHTMLRenderer expectes to handle with a dict while in this case it receives a list instead.

def get_template_context(self, data, renderer_context):
response = renderer_context['response']
if response.exception:
data['status_code'] = response.status_code
return data

Code sample

from django.test import TestCase
from rest_framework import exceptions
from rest_framework.renderers import StaticHTMLRenderer
from rest_framework.test import URLPatternsTestCase


class StaticHTMLRendererErrorTests(URLPatternsTestCase):
    class StaticErrorView(APIView):
        renderer_classes = (StaticHTMLRenderer,)

        def get(self, request, **kwargs):
            raise exceptions.ValidationError('error')

    urlpatterns = [path('error', StaticErrorView.as_view())]

    def test_statis_renderer_with_api_exception(self):
        response = self.client.get('/error')  # this line raise a TypeError
        assert response.status_code == 400

Stacktrace

TypeError: list indices must be integers or slices, not str
failed: tests/test_renderers.py:633: in test_statis_renderer_with_api_exception
    response = self.client.get('/error')
.venv/lib/python/site-packages/django/test/client.py:742: in get
    response = super().get(path, data=data, secure=secure, **extra)
.venv/lib/python/site-packages/django/test/client.py:398: in get
    **extra,
.venv/lib/python/site-packages/django/test/client.py:473: in generic
    return self.request(**r)
.venv/lib/python/site-packages/django/test/client.py:714: in request
    response = self.handler(environ)
.venv/lib/python/site-packages/django/test/client.py:145: in __call__
    response = self.get_response(request)
.venv/lib/python/site-packages/django/core/handlers/base.py:130: in get_response
    response = self._middleware_chain(request)
.venv/lib/python/site-packages/django/core/handlers/exception.py:49: in inner
    response = response_for_exception(request, exc)
.venv/lib/python/site-packages/django/core/handlers/exception.py:114: in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
.venv/lib/python/site-packages/django/core/handlers/exception.py:47: in inner
    response = get_response(request)
.venv/lib/python/site-packages/django/utils/deprecation.py:117: in __call__
    response = response or self.get_response(request)
.venv/lib/python/site-packages/django/core/handlers/exception.py:49: in inner
    response = response_for_exception(request, exc)
.venv/lib/python/site-packages/django/core/handlers/exception.py:114: in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
.venv/lib/python/site-packages/django/core/handlers/exception.py:47: in inner
    response = get_response(request)
.venv/lib/python/site-packages/django/utils/deprecation.py:117: in __call__
    response = response or self.get_response(request)
.venv/lib/python/site-packages/django/core/handlers/exception.py:49: in inner
    response = response_for_exception(request, exc)
.venv/lib/python/site-packages/django/core/handlers/exception.py:114: in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
.venv/lib/python/site-packages/django/core/handlers/exception.py:47: in inner
    response = get_response(request)
.venv/lib/python/site-packages/django/utils/deprecation.py:117: in __call__
    response = response or self.get_response(request)
.venv/lib/python/site-packages/django/core/handlers/exception.py:49: in inner
    response = response_for_exception(request, exc)
.venv/lib/python/site-packages/django/core/handlers/exception.py:114: in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
.venv/lib/python/site-packages/django/core/handlers/exception.py:47: in inner
    response = get_response(request)
.venv/lib/python/site-packages/django/utils/deprecation.py:117: in __call__
    response = response or self.get_response(request)
.venv/lib/python/site-packages/django/core/handlers/exception.py:49: in inner
    response = response_for_exception(request, exc)
.venv/lib/python/site-packages/django/core/handlers/exception.py:114: in response_for_exception
    response = handle_uncaught_exception(request, get_resolver(get_urlconf()), sys.exc_info())
.venv/lib/python/site-packages/django/core/handlers/exception.py:47: in inner
    response = get_response(request)
.venv/lib/python/site-packages/django/core/handlers/base.py:204: in _get_response
    response = response.render()
.venv/lib/python/site-packages/django/template/response.py:105: in render
    self.content = self.rendered_content
rest_framework/response.py:74: in rendered_content
    ret = renderer.render(self.data, accepted_media_type, context)
rest_framework/renderers.py:232: in render
    context = self.get_template_context(data, renderer_context)
rest_framework/renderers.py:174: in get_template_context
    data['status_code'] = response.status_code
E   TypeError: list indices must be integers or slices, not str
@auvipy
Copy link
Member

auvipy commented Mar 6, 2024

@sevdog does #9212 fix the issue?

@sevdog
Copy link
Contributor Author

sevdog commented Mar 6, 2024

@auvipy yes, it does. Running locally with that patch applied the test I wrote above succeeds.

I belive that the test should be added before merging, to avoid regression.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants