Skip to content

Commit

Permalink
Merge pull request #73 from edx/ashultz0/exceptions-frighten-newrelic
Browse files Browse the repository at this point in the history
fix: move standard error handling to where it will not bother newrelic
  • Loading branch information
ashultz0 authored Nov 20, 2023
2 parents c80ccdc + 9358f04 commit b2d0640
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 19 deletions.
2 changes: 1 addition & 1 deletion ai_aside/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@
A plugin containing xblocks and apps supporting GPT and other LLM use on edX.
"""

__version__ = '3.6.2'
__version__ = '3.7.0'

default_app_config = "ai_aside.apps.AiAsideConfig"
33 changes: 16 additions & 17 deletions ai_aside/config_api/view_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,6 @@
from ai_aside.config_api.permissions import HasStudioWriteAccess


def handle_ai_aside_exception(exc):
"""
Converts ai_aside exceptions into restframework responses
"""
if isinstance(exc, AiAsideException):
return APIResponse(http_status=exc.http_status, data={'message': str(exc)})
return None


class APIResponse(Response):
"""API Response"""
def __init__(self, data=None, http_status=None, content_type=None, success=False):
Expand All @@ -38,11 +29,19 @@ class AiAsideAPIView(APIView):
authentication_classes = (JwtAuthentication, SessionAuthentication,)
permission_classes = (HasStudioWriteAccess,)

def handle_exception(self, exc):
"""
Converts ai-aside exceptions into standard restframework responses
"""
resp = handle_ai_aside_exception(exc)
if not resp:
resp = super().handle_exception(exc)
return resp

def handle_errors(view_func):
"""
Wrapper which handles our standard exception.
We cannot do this by overriding handle_exception as you might expect,
because the newrelic wrapper sits between the view function and the
handle_exception and logs it, which makes our expected exceptions seem
harmful. So we'll handle those before newrelic can see them.
"""
def wrapped_viewfunc(self_, request, **kwargs):
try:
return view_func(self_, request, **kwargs)
except AiAsideException as exc:
return APIResponse(http_status=exc.http_status, data={'message': str(exc)})
return wrapped_viewfunc
9 changes: 8 additions & 1 deletion ai_aside/config_api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,14 @@
)
from ai_aside.config_api.exceptions import AiAsideException, AiAsideNotFoundException
from ai_aside.config_api.validators import validate_course_key, validate_unit_key
from ai_aside.config_api.view_utils import AiAsideAPIView, APIResponse
from ai_aside.config_api.view_utils import AiAsideAPIView, APIResponse, handle_errors


class CourseSummaryConfigEnabledAPIView(AiAsideAPIView):
"""
Simple GET endpoint to expose whether the course may use summary config.
"""
@handle_errors
def get(self, request, course_id=None):
"""Expose whether the course may use summary config"""
if course_id is None:
Expand All @@ -46,6 +47,7 @@ def get(self, request, course_id=None):

class CourseEnabledAPIView(AiAsideAPIView):
"""Handlers for course level settings"""
@handle_errors
def get(self, request, course_id=None):
"""Gets the enabled state for a course"""
if course_id is None:
Expand All @@ -55,6 +57,7 @@ def get(self, request, course_id=None):
settings = get_course_settings(course_key)
return APIResponse(success=True, data=settings)

@handle_errors
def post(self, request, course_id=None):
"""Update the course and reset if its necessary"""

Expand All @@ -74,6 +77,7 @@ def post(self, request, course_id=None):

return APIResponse(success=True)

@handle_errors
def delete(self, request, course_id=None):
"""Deletes the settings for a module"""

Expand All @@ -87,6 +91,7 @@ def delete(self, request, course_id=None):

class UnitEnabledAPIView(AiAsideAPIView):
"""Handlers for module level settings"""
@handle_errors
def get(self, request, course_id=None, unit_id=None):
"""Gets the enabled state for a unit"""
if course_id is None or unit_id is None:
Expand All @@ -97,6 +102,7 @@ def get(self, request, course_id=None, unit_id=None):
settings = get_unit_settings(course_key, unit_key)
return APIResponse(success=True, data=settings)

@handle_errors
def post(self, request, course_id=None, unit_id=None):
"""Sets the enabled state for a unit"""

Expand All @@ -111,6 +117,7 @@ def post(self, request, course_id=None, unit_id=None):

return APIResponse(success=True)

@handle_errors
def delete(self, request, course_id=None, unit_id=None):
"""Deletes the settings for a unit"""

Expand Down

0 comments on commit b2d0640

Please sign in to comment.