Skip to content

Commit b2d0640

Browse files
authored
Merge pull request #73 from edx/ashultz0/exceptions-frighten-newrelic
fix: move standard error handling to where it will not bother newrelic
2 parents c80ccdc + 9358f04 commit b2d0640

File tree

3 files changed

+25
-19
lines changed

3 files changed

+25
-19
lines changed

ai_aside/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
A plugin containing xblocks and apps supporting GPT and other LLM use on edX.
33
"""
44

5-
__version__ = '3.6.2'
5+
__version__ = '3.7.0'
66

77
default_app_config = "ai_aside.apps.AiAsideConfig"

ai_aside/config_api/view_utils.py

+16-17
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@
1111
from ai_aside.config_api.permissions import HasStudioWriteAccess
1212

1313

14-
def handle_ai_aside_exception(exc):
15-
"""
16-
Converts ai_aside exceptions into restframework responses
17-
"""
18-
if isinstance(exc, AiAsideException):
19-
return APIResponse(http_status=exc.http_status, data={'message': str(exc)})
20-
return None
21-
22-
2314
class APIResponse(Response):
2415
"""API Response"""
2516
def __init__(self, data=None, http_status=None, content_type=None, success=False):
@@ -38,11 +29,19 @@ class AiAsideAPIView(APIView):
3829
authentication_classes = (JwtAuthentication, SessionAuthentication,)
3930
permission_classes = (HasStudioWriteAccess,)
4031

41-
def handle_exception(self, exc):
42-
"""
43-
Converts ai-aside exceptions into standard restframework responses
44-
"""
45-
resp = handle_ai_aside_exception(exc)
46-
if not resp:
47-
resp = super().handle_exception(exc)
48-
return resp
32+
33+
def handle_errors(view_func):
34+
"""
35+
Wrapper which handles our standard exception.
36+
37+
We cannot do this by overriding handle_exception as you might expect,
38+
because the newrelic wrapper sits between the view function and the
39+
handle_exception and logs it, which makes our expected exceptions seem
40+
harmful. So we'll handle those before newrelic can see them.
41+
"""
42+
def wrapped_viewfunc(self_, request, **kwargs):
43+
try:
44+
return view_func(self_, request, **kwargs)
45+
except AiAsideException as exc:
46+
return APIResponse(http_status=exc.http_status, data={'message': str(exc)})
47+
return wrapped_viewfunc

ai_aside/config_api/views.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,14 @@
2727
)
2828
from ai_aside.config_api.exceptions import AiAsideException, AiAsideNotFoundException
2929
from ai_aside.config_api.validators import validate_course_key, validate_unit_key
30-
from ai_aside.config_api.view_utils import AiAsideAPIView, APIResponse
30+
from ai_aside.config_api.view_utils import AiAsideAPIView, APIResponse, handle_errors
3131

3232

3333
class CourseSummaryConfigEnabledAPIView(AiAsideAPIView):
3434
"""
3535
Simple GET endpoint to expose whether the course may use summary config.
3636
"""
37+
@handle_errors
3738
def get(self, request, course_id=None):
3839
"""Expose whether the course may use summary config"""
3940
if course_id is None:
@@ -46,6 +47,7 @@ def get(self, request, course_id=None):
4647

4748
class CourseEnabledAPIView(AiAsideAPIView):
4849
"""Handlers for course level settings"""
50+
@handle_errors
4951
def get(self, request, course_id=None):
5052
"""Gets the enabled state for a course"""
5153
if course_id is None:
@@ -55,6 +57,7 @@ def get(self, request, course_id=None):
5557
settings = get_course_settings(course_key)
5658
return APIResponse(success=True, data=settings)
5759

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

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

7578
return APIResponse(success=True)
7679

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

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

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

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

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

112118
return APIResponse(success=True)
113119

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

0 commit comments

Comments
 (0)