From 10fd3d89be695c4165d3be3ce84e7e639e4bf366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sascha=20I=C3=9Fbr=C3=BCcker?= Date: Sun, 7 Jun 2020 14:15:44 +0200 Subject: [PATCH] Add error handling and logging for importer --- bookmarks/services/importer.py | 30 ++++++++++++++++++++-- bookmarks/templates/settings/index.html | 22 +++++++++-------- bookmarks/views/settings.py | 33 +++++++++++++++++++------ siteroot/settings/dev.py | 2 +- 4 files changed, 66 insertions(+), 21 deletions(-) diff --git a/bookmarks/services/importer.py b/bookmarks/services/importer.py index fbfdec1..1b7a8b8 100644 --- a/bookmarks/services/importer.py +++ b/bookmarks/services/importer.py @@ -1,3 +1,5 @@ +import logging +from dataclasses import dataclass from datetime import datetime import bs4 @@ -7,14 +9,38 @@ from django.contrib.auth.models import User from bookmarks.models import Bookmark, parse_tag_string from bookmarks.services.tags import get_or_create_tags +logger = logging.getLogger(__name__) + + +@dataclass +class ImportResult: + total: int = 0 + success: int = 0 + failed: int = 0 + def import_netscape_html(html: str, user: User): - soup = BeautifulSoup(html, 'html.parser') + result = ImportResult() + + try: + soup = BeautifulSoup(html, 'html.parser') + except: + logging.exception('Could not read bookmarks file.') + raise bookmark_tags = soup.find_all('dt') for bookmark_tag in bookmark_tags: - _import_bookmark_tag(bookmark_tag, user) + result.total = result.total + 1 + try: + _import_bookmark_tag(bookmark_tag, user) + result.success = result.success + 1 + except: + shortened_bookmark_tag_str = str(bookmark_tag)[:100] + '...' + logging.exception('Error importing bookmark: ' + shortened_bookmark_tag_str) + result.failed = result.failed + 1 + + return result def _import_bookmark_tag(bookmark_tag: bs4.Tag, user: User): diff --git a/bookmarks/templates/settings/index.html b/bookmarks/templates/settings/index.html index 30950b5..b6f430f 100644 --- a/bookmarks/templates/settings/index.html +++ b/bookmarks/templates/settings/index.html @@ -17,17 +17,19 @@ - {% if import_message %} - {% if import_message.level == DEFAULT_MESSAGE_LEVELS.SUCCESS %} -
- {% endif %} - {% if import_message.level == DEFAULT_MESSAGE_LEVELS.ERROR %} -
+ {% if import_success_message %} +
+

+ {{ import_success_message }} +

+
{% endif %} -

- {{ import_message }} -

-
+ {% if import_errors_message %} +
+

+ {{ import_errors_message }} +

+
{% endif %}
diff --git a/bookmarks/views/settings.py b/bookmarks/views/settings.py index 61771d4..2e9c59d 100644 --- a/bookmarks/views/settings.py +++ b/bookmarks/views/settings.py @@ -1,3 +1,5 @@ +import logging + from django.contrib import messages from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect, HttpResponse @@ -8,24 +10,38 @@ from bookmarks.queries import query_bookmarks from bookmarks.services.exporter import export_netscape_html from bookmarks.services.importer import import_netscape_html +logger = logging.getLogger(__name__) + @login_required def index(request): - import_message = _find_message_with_tag(messages.get_messages(request), 'bookmark_import') + import_success_message = _find_message_with_tag(messages.get_messages(request), 'bookmark_import_success') + import_errors_message = _find_message_with_tag(messages.get_messages(request), 'bookmark_import_errors') return render(request, 'settings/index.html', { - 'import_message': import_message + 'import_success_message': import_success_message, + 'import_errors_message': import_errors_message, }) @login_required def bookmark_import(request): + import_file = request.FILES.get('import_file') + + if import_file is None: + messages.error(request, 'Please select a file to import.', 'bookmark_import_errors') + return HttpResponseRedirect(reverse('bookmarks:settings.index')) + try: - import_file = request.FILES.get('import_file') content = import_file.read() - import_netscape_html(content, request.user) - messages.success(request, 'Bookmarks were successfully imported.', 'bookmark_import') - except Exception: - messages.error(request, 'An error occurred during bookmark import.', 'bookmark_import') + result = import_netscape_html(content, request.user) + success_msg = str(result.success) + ' bookmarks were successfully imported.' + messages.success(request, success_msg, 'bookmark_import_success') + if result.failed > 0: + err_msg = str(result.failed) + ' bookmarks could not be imported. Please check the logs for more details.' + messages.error(request, err_msg, 'bookmark_import_errors') + except: + logging.exception('Unexpected error during bookmark import') + messages.error(request, 'An error occurred during bookmark import.', 'bookmark_import_errors') pass return HttpResponseRedirect(reverse('bookmarks:settings.index')) @@ -33,6 +49,7 @@ def bookmark_import(request): @login_required def bookmark_export(request): + # noinspection PyBroadException try: bookmarks = query_bookmarks(request.user, '') file_content = export_netscape_html(bookmarks) @@ -42,7 +59,7 @@ def bookmark_export(request): response.write(file_content) return response - except Exception: + except: return render(request, 'settings/index.html', { 'export_error': 'An error occurred during bookmark export.' }) diff --git a/siteroot/settings/dev.py b/siteroot/settings/dev.py index 560aee2..5aed862 100644 --- a/siteroot/settings/dev.py +++ b/siteroot/settings/dev.py @@ -29,7 +29,7 @@ LOGGING = { }, 'loggers': { 'django.db.backends': { - 'level': 'DEBUG', + 'level': 'ERROR', # Set to DEBUG to log all SQL calls 'handlers': ['console'], } }