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.topic import topic_by_id36
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:
@ -44,15 +45,7 @@ def unprocessable_entity(request: Request) -> Response:
if not validation_error:
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)

30
tildes/tildes/views/exceptions.py

@ -3,7 +3,15 @@
"""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.view import (
exception_view_config,
@ -15,6 +23,21 @@ from sqlalchemy import cast, desc, func, Text
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(
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):
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:
description = request.exception.explanation

Loading…
Cancel
Save