Browse Source

422 Errors: display error explanation

merge-requests/60/head
Deimos 6 years ago
parent
commit
9a33d63b96
  1. 11
      tildes/tildes/views/api/web/exceptions.py
  2. 30
      tildes/tildes/views/exceptions.py

11
tildes/tildes/views/api/web/exceptions.py

@ -18,6 +18,7 @@ from pyramid.response import Response
from tildes.resources.comment import comment_by_id36 from tildes.resources.comment import comment_by_id36
from tildes.resources.topic import topic_by_id36 from tildes.resources.topic import topic_by_id36
from tildes.views.decorators import ic_view_config from tildes.views.decorators import ic_view_config
from tildes.views.exceptions import errors_from_validationerror
def _422_response_with_errors(errors: Sequence[str]) -> Response: def _422_response_with_errors(errors: Sequence[str]) -> Response:
@ -44,15 +45,7 @@ def unprocessable_entity(request: Request) -> Response:
if not validation_error: if not validation_error:
return _422_response_with_errors([str(request.exception)]) return _422_response_with_errors([str(request.exception)])
errors_by_field = validation_error.messages
error_strings = []
for field, errors in errors_by_field.items():
joined_errors = " ".join(errors)
if field != "_schema":
error_strings.append(f"{field}: {joined_errors}")
else:
error_strings.append(joined_errors)
error_strings = errors_from_validationerror(validation_error)
return _422_response_with_errors(error_strings) return _422_response_with_errors(error_strings)

30
tildes/tildes/views/exceptions.py

@ -3,7 +3,15 @@
"""Views used by Pyramid when an exception is raised.""" """Views used by Pyramid when an exception is raised."""
from pyramid.httpexceptions import HTTPError, HTTPForbidden, HTTPNotFound
from typing import Sequence
from marshmallow import ValidationError
from pyramid.httpexceptions import (
HTTPError,
HTTPForbidden,
HTTPNotFound,
HTTPUnprocessableEntity,
)
from pyramid.request import Request from pyramid.request import Request
from pyramid.view import ( from pyramid.view import (
exception_view_config, exception_view_config,
@ -15,6 +23,21 @@ from sqlalchemy import cast, desc, func, Text
from tildes.models.group import Group from tildes.models.group import Group
def errors_from_validationerror(validation_error: ValidationError) -> Sequence[str]:
"""Extract errors from a marshmallow ValidationError into a displayable format."""
errors_by_field = validation_error.messages
error_strings = []
for field, errors in errors_by_field.items():
joined_errors = " ".join(errors)
if field != "_schema":
error_strings.append(f"{field}: {joined_errors}")
else:
error_strings.append(joined_errors)
return error_strings
@exception_view_config( @exception_view_config(
HTTPNotFound, route_name="group", renderer="error_group_not_found.jinja2" HTTPNotFound, route_name="group", renderer="error_group_not_found.jinja2"
) )
@ -44,6 +67,11 @@ def generic_error_page(request: Request) -> dict:
if isinstance(request.exception, HTTPForbidden): if isinstance(request.exception, HTTPForbidden):
description = "You don't have access to this page" description = "You don't have access to this page"
if isinstance(request.exception, HTTPUnprocessableEntity) and isinstance(
request.exception.__context__, ValidationError
):
errors = errors_from_validationerror(request.exception.__context__)
description = " ".join(errors)
else: else:
description = request.exception.explanation description = request.exception.explanation

Loading…
Cancel
Save