sns_error_notification.py 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. #! /usr/bin/env python3
  2. ''' sns_error_notification is intended as a wrapper around the `lambda_handler()`
  3. function in an AWS serverless design. It catches errors and exceptions and
  4. posts them to an sns queue, which can then be subscribed to for emails or
  5. handled by another lambda function.
  6. To use:
  7. 1) Set the environment variable 'sns_error_topic' in your lambda
  8. function to the arn of an SNS topic.
  9. 2) Ensure your lambda function has permission for `sns:Publish` to
  10. the sns topic.
  11. 3) Import this function via
  12. `from sns_error_notification import sns_error_nofication`
  13. 4) Add `@sns_error_notification` directly before your lambda_handler
  14. definition (`def lambda_handler(event, context):`)
  15. WARNING: Could potentially generate a lot of email traffic on a high
  16. volume function. Watch your execution errors metric in
  17. CloudWatch before deploying.
  18. See https://github.com/fdamstra/sns_error_notification
  19. '''
  20. import boto3
  21. import json
  22. import os
  23. import traceback
  24. def sns_error_notification(function_name):
  25. def wrapper(event, context):
  26. if os.environ.get('sns_notifications_enabled', 'true') == 'false':
  27. return function_name(event, context)
  28. try:
  29. sns_arn = os.environ.get('sns_error_topic',
  30. 'Please set an environment variable "sns_error" topic')
  31. snsclient = boto3.client('sns')
  32. function_name(event, context)
  33. except Exception as e:
  34. # First level error handling, send full details
  35. subject = f'Execution Error in {context.function_name}'
  36. estr = str(e)
  37. tb = traceback.format_exc()
  38. try:
  39. event_dump = json.dumps(event, indent=2)
  40. except:
  41. event_dump = "ERROR"
  42. try:
  43. context_dump = vars(context)
  44. except:
  45. context_dump = "ERROR"
  46. message = (f'Exception:\n{estr}\n\n'
  47. f'Traceback:\n{tb}\n\n'
  48. f'Event:\n{event_dump}\n\n'
  49. f'Context:\n{context_dump}\n'
  50. )
  51. # Only happens if there was an exception
  52. snsclient.publish(
  53. TopicArn=sns_arn,
  54. Subject=subject,
  55. Message=message
  56. )
  57. raise
  58. return wrapper