mirror of
https://github.com/GSA/notifications-api.git
synced 2026-02-01 07:35:34 -05:00
more exc_info
This commit is contained in:
@@ -265,7 +265,7 @@ def init_app(app):
|
|||||||
|
|
||||||
@app.errorhandler(Exception)
|
@app.errorhandler(Exception)
|
||||||
def exception(error):
|
def exception(error):
|
||||||
app.logger.exception(error)
|
app.logger.exception("Handling error:", exc_info=True)
|
||||||
# error.code is set for our exception types.
|
# error.code is set for our exception types.
|
||||||
msg = getattr(error, "message", str(error))
|
msg = getattr(error, "message", str(error))
|
||||||
code = getattr(error, "code", 500)
|
code = getattr(error, "code", 500)
|
||||||
@@ -353,7 +353,9 @@ def setup_sqlalchemy_events(app):
|
|||||||
"url_rule": "unknown",
|
"url_rule": "unknown",
|
||||||
}
|
}
|
||||||
except Exception:
|
except Exception:
|
||||||
current_app.logger.exception("Exception caught for checkout event.")
|
current_app.logger.exception(
|
||||||
|
"Exception caught for checkout event.", exc_info=True
|
||||||
|
)
|
||||||
|
|
||||||
@event.listens_for(db.engine, "checkin")
|
@event.listens_for(db.engine, "checkin")
|
||||||
def checkin(dbapi_connection, connection_record): # noqa
|
def checkin(dbapi_connection, connection_record): # noqa
|
||||||
@@ -403,7 +405,8 @@ def make_task(app):
|
|||||||
"Celery task {task_name} (queue: {queue_name}) failed".format(
|
"Celery task {task_name} (queue: {queue_name}) failed".format(
|
||||||
task_name=self.name,
|
task_name=self.name,
|
||||||
queue_name=self.queue_name,
|
queue_name=self.queue_name,
|
||||||
)
|
),
|
||||||
|
exc_info=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def __call__(self, *args, **kwargs):
|
def __call__(self, *args, **kwargs):
|
||||||
|
|||||||
@@ -194,7 +194,9 @@ def delete_inbound_sms():
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
current_app.logger.exception("Failed to delete inbound sms notifications")
|
current_app.logger.exception(
|
||||||
|
"Failed to delete inbound sms notifications", exc_info=True
|
||||||
|
)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ def process_ses_results(self, response):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
current_app.logger.exception("Error processing SES results: {}".format(type(e)))
|
current_app.logger.exception("Error processing SES results", exc_info=True)
|
||||||
self.retry(queue=QueueNames.RETRY)
|
self.retry(queue=QueueNames.RETRY)
|
||||||
|
|
||||||
|
|
||||||
@@ -206,7 +206,7 @@ def handle_complaint(ses_message):
|
|||||||
reference = ses_message["mail"]["messageId"]
|
reference = ses_message["mail"]["messageId"]
|
||||||
except KeyError as e:
|
except KeyError as e:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
f"Complaint from SES failed to get reference from message with error: {e}"
|
f"Complaint from SES failed to get reference from message", exc_info=True
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
notification = dao_get_notification_history_by_reference(reference)
|
notification = dao_get_notification_history_by_reference(reference)
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ def deliver_sms(self, notification_id):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
"SMS notification delivery for id: {} failed".format(notification_id)
|
"SMS notification delivery for id: {} failed".format(notification_id),
|
||||||
|
exc_info=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -188,7 +189,7 @@ def deliver_email(self, notification_id):
|
|||||||
send_to_providers.send_email_to_provider(notification)
|
send_to_providers.send_email_to_provider(notification)
|
||||||
except EmailClientNonRetryableException as e:
|
except EmailClientNonRetryableException as e:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
f"Email notification {notification_id} failed: {e}"
|
f"Email notification {notification_id} failed", exc_info=True
|
||||||
)
|
)
|
||||||
update_notification_status_by_id(notification_id, "technical-failure")
|
update_notification_status_by_id(notification_id, "technical-failure")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -199,7 +200,7 @@ def deliver_email(self, notification_id):
|
|||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
f"RETRY: Email notification {notification_id} failed"
|
f"RETRY: Email notification {notification_id} failed", exc_info=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.retry(queue=QueueNames.RETRY)
|
self.retry(queue=QueueNames.RETRY)
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ def run_scheduled_jobs():
|
|||||||
"Job ID {} added to process job queue".format(job.id)
|
"Job ID {} added to process job queue".format(job.id)
|
||||||
)
|
)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
current_app.logger.exception("Failed to run scheduled jobs")
|
current_app.logger.exception("Failed to run scheduled jobs", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ def delete_verify_codes():
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
current_app.logger.exception("Failed to delete verify codes")
|
current_app.logger.exception("Failed to delete verify codes", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ def expire_or_delete_invitations():
|
|||||||
f"Expire job started {start} finished {utc_now()} expired {expired_invites} invitations"
|
f"Expire job started {start} finished {utc_now()} expired {expired_invites} invitations"
|
||||||
)
|
)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
current_app.logger.exception("Failed to expire invitations")
|
current_app.logger.exception("Failed to expire invitations", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -84,7 +84,7 @@ def expire_or_delete_invitations():
|
|||||||
f"Delete job started {start} finished {utc_now()} deleted {deleted_invites} invitations"
|
f"Delete job started {start} finished {utc_now()} deleted {deleted_invites} invitations"
|
||||||
)
|
)
|
||||||
except SQLAlchemyError:
|
except SQLAlchemyError:
|
||||||
current_app.logger.exception("Failed to delete invitations")
|
current_app.logger.exception("Failed to delete invitations", exc_info=True)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ def handle_exception(task, notification, notification_id, exc):
|
|||||||
# SQLAlchemy is throwing a FlushError. So we check if the notification id already exists then do not
|
# SQLAlchemy is throwing a FlushError. So we check if the notification id already exists then do not
|
||||||
# send to the retry queue.
|
# send to the retry queue.
|
||||||
# This probably (hopefully) is not an issue with Redis as the celery backing store
|
# This probably (hopefully) is not an issue with Redis as the celery backing store
|
||||||
current_app.logger.exception("Retry" + retry_msg)
|
current_app.logger.exception("Retry" + retry_msg, exc_info=True)
|
||||||
try:
|
try:
|
||||||
task.retry(queue=QueueNames.RETRY, exc=exc)
|
task.retry(queue=QueueNames.RETRY, exc=exc)
|
||||||
except task.MaxRetriesExceededError:
|
except task.MaxRetriesExceededError:
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ def register_errors(blueprint):
|
|||||||
@blueprint.errorhandler(400)
|
@blueprint.errorhandler(400)
|
||||||
def bad_request(e):
|
def bad_request(e):
|
||||||
msg = e.description or "Invalid request parameters"
|
msg = e.description or "Invalid request parameters"
|
||||||
current_app.logger.exception(msg)
|
current_app.logger.exception(msg, exc_info=True)
|
||||||
return jsonify(result="error", message=str(msg)), 400
|
return jsonify(result="error", message=str(msg)), 400
|
||||||
|
|
||||||
@blueprint.errorhandler(401)
|
@blueprint.errorhandler(401)
|
||||||
@@ -91,7 +91,7 @@ def register_errors(blueprint):
|
|||||||
|
|
||||||
@blueprint.errorhandler(429)
|
@blueprint.errorhandler(429)
|
||||||
def limit_exceeded(e):
|
def limit_exceeded(e):
|
||||||
current_app.logger.exception(e)
|
current_app.logger.exception(e, exc_info=True)
|
||||||
return jsonify(result="error", message=str(e.description)), 429
|
return jsonify(result="error", message=str(e.description)), 429
|
||||||
|
|
||||||
@blueprint.errorhandler(NoResultFound)
|
@blueprint.errorhandler(NoResultFound)
|
||||||
@@ -107,7 +107,7 @@ def register_errors(blueprint):
|
|||||||
# if e is a werkzeug InternalServerError then it may wrap the original exception. For more details see:
|
# if e is a werkzeug InternalServerError then it may wrap the original exception. For more details see:
|
||||||
# https://flask.palletsprojects.com/en/1.1.x/errorhandling/?highlight=internalservererror#unhandled-exceptions
|
# https://flask.palletsprojects.com/en/1.1.x/errorhandling/?highlight=internalservererror#unhandled-exceptions
|
||||||
e = getattr(e, "original_exception", e)
|
e = getattr(e, "original_exception", e)
|
||||||
current_app.logger.exception(e)
|
current_app.logger.exception(e, exc_info=True)
|
||||||
return jsonify(result="error", message="Internal server error"), 500
|
return jsonify(result="error", message="Internal server error"), 500
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ def sns_notification_handler(data, headers):
|
|||||||
verify_message_type(message_type)
|
verify_message_type(message_type)
|
||||||
except InvalidMessageTypeException:
|
except InvalidMessageTypeException:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
f"Response headers: {headers}\nResponse data: {data}"
|
f"Response headers: {headers}\nResponse data: {data}", exc_info=True
|
||||||
)
|
)
|
||||||
raise InvalidRequest("SES-SNS callback failed: invalid message type", 400)
|
raise InvalidRequest("SES-SNS callback failed: invalid message type", 400)
|
||||||
|
|
||||||
@@ -39,7 +39,7 @@ def sns_notification_handler(data, headers):
|
|||||||
message = json.loads(data.decode("utf-8"))
|
message = json.loads(data.decode("utf-8"))
|
||||||
except decoder.JSONDecodeError:
|
except decoder.JSONDecodeError:
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
f"Response headers: {headers}\nResponse data: {data}"
|
f"Response headers: {headers}\nResponse data: {data}", exc_info=True
|
||||||
)
|
)
|
||||||
raise InvalidRequest("SES-SNS callback failed: invalid JSON given", 400)
|
raise InvalidRequest("SES-SNS callback failed: invalid JSON given", 400)
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ def handle_integrity_error(exc):
|
|||||||
),
|
),
|
||||||
400,
|
400,
|
||||||
)
|
)
|
||||||
current_app.logger.exception(exc)
|
current_app.logger.exception(exc, exc_info=True)
|
||||||
return jsonify(result="error", message="Internal server error"), 500
|
return jsonify(result="error", message="Internal server error"), 500
|
||||||
|
|
||||||
|
|
||||||
@@ -838,7 +838,7 @@ def update_guest_list(service_id):
|
|||||||
try:
|
try:
|
||||||
guest_list_objects = get_guest_list_objects(service_id, request.get_json())
|
guest_list_objects = get_guest_list_objects(service_id, request.get_json())
|
||||||
except ValueError as e:
|
except ValueError as e:
|
||||||
current_app.logger.exception(e)
|
current_app.logger.exception(e, exc_info=True)
|
||||||
dao_rollback()
|
dao_rollback()
|
||||||
msg = "{} is not a valid email address or phone number".format(str(e))
|
msg = "{} is not a valid email address or phone number".format(str(e))
|
||||||
raise InvalidRequest(msg, 400)
|
raise InvalidRequest(msg, 400)
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ def handle_integrity_error(exc):
|
|||||||
if "ck_user_has_mobile_or_other_auth" in str(exc):
|
if "ck_user_has_mobile_or_other_auth" in str(exc):
|
||||||
# we don't expect this to trip, so still log error
|
# we don't expect this to trip, so still log error
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
"Check constraint ck_user_has_mobile_or_other_auth triggered"
|
"Check constraint ck_user_has_mobile_or_other_auth triggered", exc_info=True
|
||||||
)
|
)
|
||||||
return (
|
return (
|
||||||
jsonify(
|
jsonify(
|
||||||
|
|||||||
@@ -166,7 +166,7 @@ class RedisClient:
|
|||||||
|
|
||||||
def __handle_exception(self, e, raise_exception, operation, key_name):
|
def __handle_exception(self, e, raise_exception, operation, key_name):
|
||||||
current_app.logger.exception(
|
current_app.logger.exception(
|
||||||
"Redis error performing {} on {}".format(operation, key_name)
|
"Redis error performing {} on {}".format(operation, key_name), exc_info=True
|
||||||
)
|
)
|
||||||
if raise_exception:
|
if raise_exception:
|
||||||
raise e
|
raise e
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ def test_cronitor_does_nothing_if_name_not_recognised(notify_api, rmock, mocker)
|
|||||||
assert successful_task() == 1
|
assert successful_task() == 1
|
||||||
|
|
||||||
mock_logger.error.assert_called_with(
|
mock_logger.error.assert_called_with(
|
||||||
"Cronitor enabled but task_name hello not found in environment"
|
"Cronitor enabled but task_name hello not found in environment", exc_info=True
|
||||||
)
|
)
|
||||||
|
|
||||||
assert rmock.called is False
|
assert rmock.called is False
|
||||||
|
|||||||
Reference in New Issue
Block a user