diff --git a/app/main/views/notifications.py b/app/main/views/notifications.py index 5b2a2d99e..1277da379 100644 --- a/app/main/views/notifications.py +++ b/app/main/views/notifications.py @@ -24,6 +24,7 @@ from notifications_utils.letter_timings import ( ) from notifications_utils.pdf import pdf_page_count from notifications_utils.timezones import utc_string_to_aware_gmt_datetime +from PyPDF2.utils import PdfReadError from app import ( _format_datetime_short, @@ -58,8 +59,14 @@ def view_notification(service_id, notification_id): personalisation = get_all_personalisation_from_notification(notification) if notification['template']['is_precompiled_letter']: - file_contents = view_letter_notification_as_preview(service_id, notification_id, "pdf") - page_count = pdf_page_count(io.BytesIO(file_contents)) + try: + file_contents = view_letter_notification_as_preview(service_id, notification_id, "pdf") + page_count = pdf_page_count(io.BytesIO(file_contents)) + except PdfReadError: + return render_template( + 'views/notifications/invalid_precompiled_letter.html', + created_at=notification['created_at'] + ) else: page_count = get_page_count_for_letter(notification['template'], values=personalisation) diff --git a/app/templates/views/notifications/invalid_precompiled_letter.html b/app/templates/views/notifications/invalid_precompiled_letter.html new file mode 100644 index 000000000..de26ec624 --- /dev/null +++ b/app/templates/views/notifications/invalid_precompiled_letter.html @@ -0,0 +1,17 @@ +{% extends "withnav_template.html" %} + +{% block service_page_title %} + Letter +{% endblock %} + +{% block maincolumn_content %} + +

Letter

+ +

+ Provided as PDF on {{ created_at|format_datetime_short }} +

+

+ Couldn’t read this file +

+{% endblock %} diff --git a/tests/app/main/views/test_notifications.py b/tests/app/main/views/test_notifications.py index 353c6bc94..c27a601bf 100644 --- a/tests/app/main/views/test_notifications.py +++ b/tests/app/main/views/test_notifications.py @@ -7,6 +7,7 @@ import pytest from flask import url_for from freezegun import freeze_time from notifications_python_client.errors import APIError +from PyPDF2.utils import PdfReadError from app.main.views.notifications import get_letter_printing_statement from tests.conftest import ( @@ -398,6 +399,36 @@ def test_should_show_preview_error_image_letter_notification_on_preview_error( assert response.get_data(as_text=True) == 'preview error image' +def test_notifification_page_shows_error_message_if_precompiled_letter_cannot_be_opened( + client_request, + mocker, + fake_uuid, +): + mock_get_notification( + mocker, + fake_uuid, + notification_status='validation-failed', + template_type='letter', + is_precompiled_letter=True, + ) + mocker.patch( + 'app.main.views.notifications.view_letter_notification_as_preview', + side_effect=PdfReadError() + ) + mocker.patch( + 'app.main.views.notifications.pdf_page_count', + side_effect=PdfReadError() + ) + page = client_request.get( + 'main.view_notification', + service_id=SERVICE_ONE_ID, + notification_id=fake_uuid, + ) + + error_message = page.find('p', class_='notification-status-cancelled').text + assert normalize_spaces(error_message) == "Couldn’t read this file" + + def test_should_404_for_unknown_extension( client_request, fake_uuid,