mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-23 15:57:23 -04:00
Merge pull request #4159 from alphagov/catch-missing-letter
Catch error if letter does not exist on send
This commit is contained in:
@@ -7,7 +7,6 @@ from functools import partial
|
||||
from io import BytesIO
|
||||
from zipfile import BadZipFile
|
||||
|
||||
from botocore.exceptions import ClientError
|
||||
from flask import (
|
||||
abort,
|
||||
current_app,
|
||||
@@ -39,6 +38,7 @@ from app.main import main
|
||||
from app.main.forms import CsvUploadForm, LetterUploadPostageForm, PDFUploadForm
|
||||
from app.models.contact_list import ContactList
|
||||
from app.s3_client.s3_letter_upload_client import (
|
||||
LetterNotFoundError,
|
||||
backup_original_letter_to_s3,
|
||||
get_letter_metadata,
|
||||
get_letter_pdf_and_metadata,
|
||||
@@ -267,17 +267,18 @@ def uploaded_letter_preview(service_id, file_id):
|
||||
|
||||
try:
|
||||
metadata = get_letter_metadata(service_id, file_id)
|
||||
except ClientError as e:
|
||||
# if the file's not there, it's probably because we've already created the notification and the letter has been
|
||||
# moved to the normal letters-pdf bucket. So lets just bounce out to the notification page
|
||||
if e.response['Error']['Code'] == 'NoSuchKey':
|
||||
return redirect(url_for(
|
||||
'.view_notification',
|
||||
service_id=service_id,
|
||||
notification_id=file_id,
|
||||
))
|
||||
else:
|
||||
raise
|
||||
except LetterNotFoundError as e:
|
||||
current_app.logger.warning(e)
|
||||
|
||||
# If the file is missing it could be because this is a duplicate
|
||||
# request, the notification already exists and the file has been
|
||||
# moved to a different bucket. Note that the ID of a precompiled
|
||||
# notification is always set to the file_id.
|
||||
return redirect(url_for(
|
||||
'.view_notification',
|
||||
service_id=service_id,
|
||||
notification_id=file_id,
|
||||
))
|
||||
|
||||
original_filename = metadata.get('filename')
|
||||
page_count = metadata.get('page_count')
|
||||
@@ -352,7 +353,20 @@ def send_uploaded_letter(service_id, file_id):
|
||||
if not current_service.has_permission('letter'):
|
||||
abort(403)
|
||||
|
||||
metadata = get_letter_metadata(service_id, file_id)
|
||||
try:
|
||||
metadata = get_letter_metadata(service_id, file_id)
|
||||
except LetterNotFoundError as e:
|
||||
current_app.logger.error(e)
|
||||
|
||||
# If the file is missing it could be because this is a duplicate
|
||||
# request, the notification already exists and the file has been
|
||||
# moved to a different bucket. Note that the ID of a precompiled
|
||||
# notification is always set to the file_id.
|
||||
return redirect(url_for(
|
||||
'.view_notification',
|
||||
service_id=service_id,
|
||||
notification_id=file_id,
|
||||
))
|
||||
|
||||
if metadata.get('status') != 'valid':
|
||||
abort(403)
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
import json
|
||||
import urllib
|
||||
|
||||
import botocore
|
||||
from boto3 import resource
|
||||
from flask import current_app
|
||||
from notifications_utils.s3 import s3upload as utils_s3upload
|
||||
|
||||
|
||||
class LetterNotFoundError(Exception):
|
||||
pass
|
||||
|
||||
|
||||
def get_transient_letter_file_location(service_id, upload_id):
|
||||
return 'service-{}/{}.pdf'.format(service_id, upload_id)
|
||||
|
||||
@@ -69,19 +74,24 @@ class LetterMetadata:
|
||||
return value
|
||||
|
||||
|
||||
def get_letter_s3_object(service_id, file_id):
|
||||
try:
|
||||
file_location = get_transient_letter_file_location(service_id, file_id)
|
||||
s3 = resource('s3')
|
||||
return s3.Object(current_app.config['TRANSIENT_UPLOADED_LETTERS'], file_location).get()
|
||||
except botocore.exceptions.ClientError as e:
|
||||
if e.response['Error']['Code'] == 'NoSuchKey':
|
||||
raise LetterNotFoundError(f'Letter not found for service {service_id} and file {file_id}')
|
||||
|
||||
raise
|
||||
|
||||
|
||||
def get_letter_pdf_and_metadata(service_id, file_id):
|
||||
file_location = get_transient_letter_file_location(service_id, file_id)
|
||||
s3 = resource('s3')
|
||||
s3_object = s3.Object(current_app.config['TRANSIENT_UPLOADED_LETTERS'], file_location).get()
|
||||
|
||||
s3_object = get_letter_s3_object(service_id, file_id)
|
||||
pdf = s3_object['Body'].read()
|
||||
|
||||
return pdf, LetterMetadata(s3_object['Metadata'])
|
||||
|
||||
|
||||
def get_letter_metadata(service_id, file_id):
|
||||
file_location = get_transient_letter_file_location(service_id, file_id)
|
||||
s3 = resource('s3')
|
||||
s3_object = s3.Object(current_app.config['TRANSIENT_UPLOADED_LETTERS'], file_location).get()
|
||||
|
||||
s3_object = get_letter_s3_object(service_id, file_id)
|
||||
return LetterMetadata(s3_object['Metadata'])
|
||||
|
||||
Reference in New Issue
Block a user