pyceo/ceod/api/error_handlers.py

54 lines
2.0 KiB
Python

import traceback
from flask import request
from flask.app import Flask
import ldap3
from werkzeug.exceptions import HTTPException
from ceo_common.errors import UserNotFoundError, GroupNotFoundError, \
UserAlreadyExistsError, GroupAlreadyExistsError, BadRequest, \
UserAlreadySubscribedError, InvalidMembershipError, \
CloudStackAPIError, InvalidDomainError, InvalidIPError, RateLimitError
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):
"""Return JSON for all errors."""
if isinstance(err, HTTPException):
status_code = err.code
elif any(isinstance(err, cls) for cls in [
BadRequest, InvalidDomainError, InvalidIPError
]):
status_code = 400
elif any(isinstance(err, cls) for cls in [
ldap3.core.exceptions.LDAPStrongerAuthRequiredResult,
InvalidMembershipError, RateLimitError,
]):
status_code = 403
elif isinstance(err, UserNotFoundError) or isinstance(err, GroupNotFoundError):
status_code = 404
elif any(isinstance(err, cls) for cls in [
UserAlreadyExistsError, GroupAlreadyExistsError, UserAlreadySubscribedError
]):
status_code = 409
elif isinstance(err, CloudStackAPIError):
status_code = 500
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')
return {'error': type(err).__name__ + ': ' + str(err)}, status_code