mirror of
https://github.com/GSA/notifications-api.git
synced 2025-12-24 01:11:38 -05:00
they do not raise exceptions. Introduced a simple exception that contains error messages and status code that can be used rather than return json + status code from rest methods directly. The handler in errors for this exception can then log the error before returning json.
93 lines
3.1 KiB
Python
93 lines
3.1 KiB
Python
from flask import (
|
|
jsonify,
|
|
current_app
|
|
)
|
|
from sqlalchemy.exc import SQLAlchemyError, DataError
|
|
from sqlalchemy.orm.exc import NoResultFound
|
|
|
|
|
|
class InvalidData(Exception):
|
|
|
|
def __init__(self, message, status_code):
|
|
super().__init__()
|
|
self.message = message
|
|
self.status_code = status_code
|
|
|
|
def to_dict(self):
|
|
return {'result': 'error', 'message': self.message}
|
|
|
|
def __str__(self):
|
|
return str(self.to_dict())
|
|
|
|
|
|
def register_errors(blueprint):
|
|
|
|
@blueprint.app_errorhandler(InvalidData)
|
|
def invalid_data(error):
|
|
response = jsonify(error.to_dict())
|
|
response.status_code = error.status_code
|
|
current_app.logger.error(error)
|
|
return response
|
|
|
|
@blueprint.app_errorhandler(400)
|
|
def bad_request(e):
|
|
if isinstance(e, str):
|
|
msg = e
|
|
else:
|
|
msg = e.description or "Invalid request parameters"
|
|
current_app.logger.exception(msg)
|
|
return jsonify(result='error', message=str(msg)), 400
|
|
|
|
@blueprint.app_errorhandler(401)
|
|
def unauthorized(e):
|
|
error_message = "Unauthorized, authentication token must be provided"
|
|
return jsonify(result='error', message=error_message), 401, [('WWW-Authenticate', 'Bearer')]
|
|
|
|
@blueprint.app_errorhandler(403)
|
|
def forbidden(e):
|
|
error_message = "Forbidden, invalid authentication token provided"
|
|
return jsonify(result='error', message=error_message), 403
|
|
|
|
@blueprint.app_errorhandler(404)
|
|
def page_not_found(e):
|
|
if isinstance(e, str):
|
|
msg = e
|
|
else:
|
|
msg = e.description or "Not found"
|
|
current_app.logger.exception(msg)
|
|
return jsonify(result='error', message=msg), 404
|
|
|
|
@blueprint.app_errorhandler(429)
|
|
def limit_exceeded(e):
|
|
current_app.logger.exception(e)
|
|
return jsonify(result='error', message=str(e.description)), 429
|
|
|
|
@blueprint.app_errorhandler(500)
|
|
def internal_server_error(e):
|
|
current_app.logger.exception(e)
|
|
return jsonify(result='error', message="Internal server error"), 500
|
|
|
|
@blueprint.app_errorhandler(NoResultFound)
|
|
def no_result_found(e):
|
|
current_app.logger.exception(e)
|
|
return jsonify(result='error', message="No result found"), 404
|
|
|
|
@blueprint.app_errorhandler(DataError)
|
|
def data_error(e):
|
|
current_app.logger.exception(e)
|
|
return jsonify(result='error', message="No result found"), 404
|
|
|
|
@blueprint.app_errorhandler(SQLAlchemyError)
|
|
def db_error(e):
|
|
current_app.logger.exception(e)
|
|
if e.orig.pgerror and \
|
|
('duplicate key value violates unique constraint "services_name_key"' in e.orig.pgerror or
|
|
'duplicate key value violates unique constraint "services_email_from_key"' in e.orig.pgerror):
|
|
return jsonify(
|
|
result='error',
|
|
message={'name': ["Duplicate service name '{}'".format(
|
|
e.params.get('name', e.params.get('email_from', ''))
|
|
)]}
|
|
), 400
|
|
return jsonify(result='error', message="Internal server error"), 500
|