"""Lambda function module.""" import json from urllib import parse from constants import common import common_config from constants import email import ses import sentry def parse_dlq_message(event): """Parse SNS message sent by DLQ. Args: event (dict): SNS event Returns: dict: error details """ records = event.get('Records') if not records: return {} sns = records[0].get('Sns') if sns: message = json.loads(records[0]['Sns']['Message']) s3_event = message.get('s3_event')['Records'][0] elif records[0].get('s3'): s3_event = records[0] else: return{} context = parse_s3_event(s3_event) context['error_detail'] = email.PROCESSING_ERROR return context def parse_s3_event(event): """Parse the original S3 event. Args: event (dict): s3 event from message payload (['Records'][0]) Returns: dict: error details """ key = event['s3']['object']['key'] full_file_name = key.split('/')[-1] upload_timestamp = event['eventTime'] return { 'full_file_name': parse.unquote_plus(full_file_name), 'upload_timestamp': upload_timestamp, } def prepare_message_body(template, message): """Prepare e-mail message body. Args: template (str): E-mail template message (dict): SNS message with error details. Returns: str: E-mail message body """ s3_event = message.get('s3_event') error_detail = '' if s3_event: context = parse_s3_event(s3_event['Records'][0]) verification_error = message.get('detailed', '') if verification_error: error_detail = '
{}
'.format(verification_error) else: context = parse_dlq_message(message) if not context: return '' if context.get('error_detail') is None: context['error_detail'] = error_detail context['workflow_link'] = email.WORKFLOW_LINK return template.format(**context) @sentry.sentry_capture_exception def handler(event, context): """Lambda entry point.""" if common_config.IGNORE_ALL_EVENTS is not None: common_config.logger.warning(common.IGNORE_MESSAGE) return common_config.logger.info('Starting to process failure SNS message.') message = json.loads(event['Records'][0]['Sns']['Message']) body = prepare_message_body(email.ATTACHMENT_ERROR_BODY, message) if not body: common_config.logger.info( 'Cannot parse DLQ event. Ignoring.') return common_config.logger.info('Sending an E-mail.') ses.send_email( recipient=common_config.ERROR_ATTACHMENT_EMAIL_RECIPIENT, sender=common_config.EMAIL_SENDER, subject=email.ATTACHMENT_ERROR_SUBJECT, message=body) common_config.logger.info('Done.')