mirror of
https://github.com/freedombox/FreedomBox.git
synced 2026-08-26 12:46:08 +00:00
views: Add a decorator to handle exceptions in JSON views
Signed-off-by: Sunil Mohan Adapa <sunil@medhas.org> Reviewed-by: James Valleroy <jvalleroy@mailbox.org>
This commit is contained in:
parent
cc626be728
commit
46f13b2be9
@ -3,10 +3,13 @@
|
|||||||
Tests for common FreedomBox views.
|
Tests for common FreedomBox views.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import json
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
from django.http import JsonResponse
|
||||||
from django.urls import resolve
|
from django.urls import resolve
|
||||||
|
|
||||||
from plinth.views import get_breadcrumbs, is_safe_url
|
from plinth.views import get_breadcrumbs, is_safe_url, json_exception
|
||||||
|
|
||||||
|
|
||||||
def test_get_breadcrumbs(rf, test_menu):
|
def test_get_breadcrumbs(rf, test_menu):
|
||||||
@ -82,3 +85,31 @@ def test_is_safe_url_valid_url(url):
|
|||||||
def test_is_safe_url_invalid_url(url):
|
def test_is_safe_url_invalid_url(url):
|
||||||
"""Test invalid URLs for safe URL checks."""
|
"""Test invalid URLs for safe URL checks."""
|
||||||
assert not is_safe_url(url)
|
assert not is_safe_url(url)
|
||||||
|
|
||||||
|
|
||||||
|
def test_json_exception(rf):
|
||||||
|
"""Test handling exceptions in JSON views."""
|
||||||
|
|
||||||
|
@json_exception
|
||||||
|
def error_view(request):
|
||||||
|
raise Exception('exception-message')
|
||||||
|
|
||||||
|
assert error_view.__name__ == 'error_view'
|
||||||
|
|
||||||
|
request = rf.get('')
|
||||||
|
response = error_view(request)
|
||||||
|
assert response.status_code == 500
|
||||||
|
json_content = json.loads(response.content)
|
||||||
|
assert not json_content['result']
|
||||||
|
assert json_content['error_name'] == 'Exception'
|
||||||
|
assert json_content['error_string'] == 'exception-message'
|
||||||
|
|
||||||
|
def success_view(request):
|
||||||
|
return JsonResponse({'result': True, 'error_string': None})
|
||||||
|
|
||||||
|
request = rf.get('')
|
||||||
|
response = success_view(request)
|
||||||
|
assert response.status_code == 200
|
||||||
|
json_content = json.loads(response.content)
|
||||||
|
assert json_content['result']
|
||||||
|
assert json_content['error_string'] is None
|
||||||
|
|||||||
@ -3,10 +3,13 @@
|
|||||||
Main FreedomBox views.
|
Main FreedomBox views.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import functools
|
||||||
|
import logging
|
||||||
import random
|
import random
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
import urllib.parse
|
import urllib.parse
|
||||||
|
from collections.abc import Callable
|
||||||
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
@ -33,6 +36,8 @@ from plinth.translation import get_language_from_request, set_language
|
|||||||
|
|
||||||
from . import forms, frontpage, operation, setup
|
from . import forms, frontpage, operation, setup
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
REDIRECT_FIELD_NAME = 'next'
|
REDIRECT_FIELD_NAME = 'next'
|
||||||
|
|
||||||
|
|
||||||
@ -683,6 +688,7 @@ class AppLogsView(TemplateView):
|
|||||||
def notification_dismiss(request, id):
|
def notification_dismiss(request, id):
|
||||||
"""Dismiss a notification."""
|
"""Dismiss a notification."""
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
|
|
||||||
from .notification import Notification
|
from .notification import Notification
|
||||||
notes = Notification.list(key=id, user=request.user)
|
notes = Notification.list(key=id, user=request.user)
|
||||||
if notes:
|
if notes:
|
||||||
@ -697,3 +703,24 @@ def notification_dismiss(request, id):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
return HttpResponseRedirect(_get_redirect_url_from_param(request))
|
return HttpResponseRedirect(_get_redirect_url_from_param(request))
|
||||||
|
|
||||||
|
|
||||||
|
def json_exception(view_func: Callable):
|
||||||
|
"""View decorator to return an view exception in JSON format."""
|
||||||
|
|
||||||
|
@functools.wraps(view_func)
|
||||||
|
def wrapper(*args, **kwargs):
|
||||||
|
"""Wrapper over view function to handle exceptions."""
|
||||||
|
try:
|
||||||
|
return view_func(*args, **kwargs)
|
||||||
|
except Exception as exception:
|
||||||
|
logger.exception('Error running view %s - %s', view_func.__name__,
|
||||||
|
exception)
|
||||||
|
return JsonResponse(
|
||||||
|
{
|
||||||
|
'result': False,
|
||||||
|
'error_name': type(exception).__name__,
|
||||||
|
'error_string': str(exception)
|
||||||
|
}, status=500) # Internal server error
|
||||||
|
|
||||||
|
return wrapper
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user