Skip to content

Commit

Permalink
fix: update error handling and add logger.info in BFF (#607)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamstankiewicz authored Dec 4, 2024
1 parent ec0bef8 commit ffe9285
Show file tree
Hide file tree
Showing 7 changed files with 269 additions and 130 deletions.
25 changes: 22 additions & 3 deletions enterprise_access/apps/api/v1/views/bffs/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ def load_route_data_and_build_response(self, request, handler_class, response_bu
# Create the context based on the request
context = HandlerContext(request=request)
except Exception as exc: # pylint: disable=broad-except
logger.exception("Could not create the handler context.")
logger.exception("Could not instantiate the handler context for the request.")
error = {
'user_message': 'An error occurred while processing the request.',
'developer_message': f'Could not create the handler context. Error: {exc}',
Expand All @@ -62,14 +62,33 @@ def load_route_data_and_build_response(self, request, handler_class, response_bu
try:
# Create the route handler
handler = handler_class(context)
except Exception as exc: # pylint: disable=broad-except
logger.exception(
"Could not instantiate route handler (%s) for request user %s and enterprise customer %s.",
handler_class.__name__,
context.lms_user_id,
context.enterprise_customer_uuid,
)
context.add_error(
user_message='An error occurred while processing the request.',
developer_message=f'Could not instantiate route handler ({handler_class.__name__}). Error: {exc}',
)

try:
# Load and process route data
handler.load_and_process()
except Exception as exc: # pylint: disable=broad-except
logger.exception("Could not create route handler or load/process route data.")
logger.exception(
"Could not load/process route handler (%s) for request user %s and enterprise customer %s.",
handler_class.__name__,
context.lms_user_id,
context.enterprise_customer_uuid,
)
context.add_error(
user_message='An error occurred while processing the request.',
developer_message=f'Could not create route handler or load/process route data. Error: {exc}',
developer_message=(
f'Could not load/process data for route handler ({handler_class.__name__}). Error: {exc}',
),
)

# Build the response data and status code
Expand Down
90 changes: 69 additions & 21 deletions enterprise_access/apps/bffs/context.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ class HandlerContext:
enterprise_customer_slug: The enterprise customer slug associated with this request.
lms_user_id: The id associated with the authenticated user.
enterprise_features: A dictionary to store enterprise features associated with the authenticated user.
enterprise_customer: The enterprise customer associated with the request.
active_enterprise_customer: The active enterprise customer associated with the request user.
all_linked_enterprise_customer_users: A list of all linked enterprise customer users
associated with the request user.
staff_enterprise_customer: The enterprise customer, if resolved as a staff request user.
is_request_user_linked_to_enterprise_customer: A boolean indicating if the request user is linked
to the resolved enterprise customer.
status_code: The HTTP status code to return in the response.
"""

def __init__(self, request):
Expand Down Expand Up @@ -118,6 +126,12 @@ def is_request_user_linked_to_enterprise_customer(self):
def staff_enterprise_customer(self):
return self.data.get('staff_enterprise_customer')

def set_status_code(self, status_code):
"""
Sets the status code for the response.
"""
self._status_code = status_code

def _initialize_common_context_data(self):
"""
Initializes common context data, like enterprise customer UUID and user ID.
Expand All @@ -137,10 +151,40 @@ def _initialize_common_context_data(self):
self._enterprise_customer_slug = enterprise_customer_slug

# Initialize the enterprise customer users metatata derived from the LMS
self._initialize_enterprise_customer_users()
try:
self._initialize_enterprise_customer_users()
except Exception as exc: # pylint: disable=broad-except
logger.exception(
'Error initializing enterprise customer users for request user %s, '
'enterprise customer uuid %s and/or slug %s',
self.lms_user_id,
enterprise_customer_uuid,
enterprise_customer_slug,
)
self.add_error(
user_message='Error initializing enterprise customer users',
developer_message=f'Could not initialize enterprise customer users. Error: {exc}',
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
)
return

if not self.enterprise_customer:
# If no enterprise customer is found, return early
logger.info(
'No enterprise customer found for request user %s, enterprise customer uuid %s, '
'and/or enterprise slug %s',
self.lms_user_id,
enterprise_customer_uuid,
enterprise_customer_slug,
)
self.add_error(
user_message='No enterprise customer found',
developer_message=(
f'No enterprise customer found for request user {self.lms_user_id} and enterprise uuid '
f'{enterprise_customer_uuid}, and/or enterprise slug {enterprise_customer_slug}'
),
status_code=status.HTTP_404_NOT_FOUND,
)
return

# Otherwise, update the enterprise customer UUID and slug if not already set
Expand All @@ -153,18 +197,10 @@ def _initialize_enterprise_customer_users(self):
"""
Initializes the enterprise customer users for the request user.
"""
try:
enterprise_customer_users_data = get_and_cache_enterprise_customer_users(
self.request,
traverse_pagination=True
)
except Exception as exc: # pylint: disable=broad-except
logger.exception('Error retrieving linked enterprise customers')
self.add_error(
user_message='Error retrieving linked enterprise customers',
developer_message=f'Could not fetch enterprise customer users. Error: {exc}'
)
return
enterprise_customer_users_data = get_and_cache_enterprise_customer_users(
self.request,
traverse_pagination=True
)

# Set enterprise features from the response
self._enterprise_features = enterprise_customer_users_data.get('enterprise_features', {})
Expand All @@ -178,33 +214,45 @@ def _initialize_enterprise_customer_users(self):
enterprise_customer_slug=self.enterprise_customer_slug,
enterprise_customer_uuid=self.enterprise_customer_uuid,
)
except Exception as exc: # pylint: disable=broad-except
logger.exception('Error transforming enterprise customer users data')
self.add_error(
user_message='Error transforming enterprise customer users data',
developer_message=f'Could not transform enterprise customer users data. Error: {exc}'
except Exception: # pylint: disable=broad-except
logger.exception(
'Error transforming enterprise customer users metadata for request user %s, '
'enterprise customer uuid %s and/or slug %s',
self.lms_user_id,
self.enterprise_customer_uuid,
self.enterprise_customer_slug,
)

# Update the context data with the transformed enterprise customer users data
self.data.update({
'enterprise_customer': transformed_data.get('enterprise_customer'),
'active_enterprise_customer': transformed_data.get('active_enterprise_customer'),
'all_linked_enterprise_customer_users': transformed_data.get('all_linked_enterprise_customer_users', []),
'staff_enterprise_customer': transformed_data.get('staff_enterprise_customer'),
})

def add_error(self, **kwargs):
def add_error(self, status_code=None, **kwargs):
"""
Adds an error to the context.
Output fields determined by the ErrorSerializer
Args:
user_message (str): A user-friendly message describing the error.
developer_message (str): A message describing the error for developers.
[status_code] (int): The HTTP status code to return in the response.
"""
serializer = serializers.ErrorSerializer(data=kwargs)
serializer.is_valid(raise_exception=True)
self.errors.append(serializer.data)
if status_code:
self.set_status_code(status_code)

def add_warning(self, **kwargs):
"""
Adds a warning to the context.
Output fields determined by the WarningSerializer
Args:
user_message (str): A user-friendly message describing the error.
developer_message (str): A message describing the error for developers.
"""
serializer = serializers.WarningSerializer(data=kwargs)
serializer.is_valid(raise_exception=True)
Expand Down
Loading

0 comments on commit ffe9285

Please sign in to comment.