pyceo/ceod/api/error_handlers.py

54 lines
2.0 KiB
Python
Raw Normal View History

2021-08-03 19:19:33 -04:00
import traceback
from flask import request
2021-08-03 19:19:33 -04:00
from flask.app import Flask
2021-08-21 02:27:33 -04:00
import ldap3
2021-08-03 19:19:33 -04:00
from werkzeug.exceptions import HTTPException
from ceo_common.errors import UserNotFoundError, GroupNotFoundError, \
UserAlreadyExistsError, GroupAlreadyExistsError, BadRequest, \
UserAlreadySubscribedError, InvalidMembershipError, \
2021-11-28 22:35:46 -05:00
CloudStackAPIError, InvalidDomainError, InvalidIPError, RateLimitError
2021-08-03 19:19:33 -04:00
from ceo_common.logger_factory import logger_factory
__all__ = ['register_error_handlers']
logger = logger_factory(__name__)
def register_error_handlers(app: Flask):
"""Register error handlers for the application."""
app.register_error_handler(Exception, generic_error_handler)
def generic_error_handler(err: Exception):
2021-08-19 00:56:25 -04:00
"""Return JSON for all errors."""
2021-08-03 19:19:33 -04:00
if isinstance(err, HTTPException):
2021-08-19 00:56:25 -04:00
status_code = err.code
elif any(isinstance(err, cls) for cls in [
BadRequest, InvalidDomainError, InvalidIPError
]):
status_code = 400
2021-11-28 22:35:46 -05:00
elif any(isinstance(err, cls) for cls in [
ldap3.core.exceptions.LDAPStrongerAuthRequiredResult,
InvalidMembershipError, RateLimitError,
]):
status_code = 403
2021-08-19 00:56:25 -04:00
elif isinstance(err, UserNotFoundError) or isinstance(err, GroupNotFoundError):
2021-08-18 19:48:17 -04:00
status_code = 404
elif any(isinstance(err, cls) for cls in [
UserAlreadyExistsError, GroupAlreadyExistsError, UserAlreadySubscribedError
]):
status_code = 409
elif isinstance(err, CloudStackAPIError):
status_code = 500
2021-08-18 19:48:17 -04:00
else:
status_code = 500
logger.error(traceback.format_exc())
if request.path.startswith('/api/cloud'):
# I've noticed that the requests library spits out the
# full URL when an Exception is raised, which will cause
# our CloudStack API key to be leaked. So we're going to mask
# it here instead.
err = Exception('Please contact the Systems Committee')
2021-08-18 19:48:17 -04:00
return {'error': type(err).__name__ + ': ' + str(err)}, status_code