From 0c82bae91c19f88d6cec5672dfa1f4337a54dc77 Mon Sep 17 00:00:00 2001 From: Calen Pennington Date: Wed, 12 Apr 2017 15:37:38 -0400 Subject: [PATCH] Add the caller to user_api caught error logging --- openedx/core/djangoapps/user_api/helpers.py | 8 +++++-- .../djangoapps/user_api/tests/test_helpers.py | 22 +++++++++++++++---- 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/openedx/core/djangoapps/user_api/helpers.py b/openedx/core/djangoapps/user_api/helpers.py index c2c62d6618..851bf4914c 100644 --- a/openedx/core/djangoapps/user_api/helpers.py +++ b/openedx/core/djangoapps/user_api/helpers.py @@ -6,6 +6,7 @@ from collections import defaultdict from functools import wraps import logging import json +import traceback from django import forms from django.core.serializers.json import DjangoJSONEncoder @@ -65,16 +66,19 @@ def intercept_errors(api_error, ignore_errors=None): LOGGER.warning(msg) raise + caller = traceback.format_stack(limit=2)[0] + # Otherwise, log the error and raise the API-specific error msg = ( u"An unexpected error occurred when calling '{func_name}' " - u"with arguments '{args}' and keyword arguments '{kwargs}': " + u"with arguments '{args}' and keyword arguments '{kwargs}' from {caller}: " u"{exception}" ).format( func_name=func.func_name, args=args, kwargs=kwargs, - exception=ex.developer_message if hasattr(ex, 'developer_message') else repr(ex) + exception=ex.developer_message if hasattr(ex, 'developer_message') else repr(ex), + caller=caller.strip() ) LOGGER.exception(msg) raise api_error(msg) diff --git a/openedx/core/djangoapps/user_api/tests/test_helpers.py b/openedx/core/djangoapps/user_api/tests/test_helpers.py index a0983a0573..00576d588e 100644 --- a/openedx/core/djangoapps/user_api/tests/test_helpers.py +++ b/openedx/core/djangoapps/user_api/tests/test_helpers.py @@ -2,6 +2,7 @@ Tests for helper functions. """ import json +import re import mock import ddt from django import forms @@ -52,22 +53,35 @@ class InterceptErrorsTest(TestCase): @mock.patch('openedx.core.djangoapps.user_api.helpers.LOGGER') def test_logs_errors(self, mock_logger): + self.maxDiff = None exception = 'openedx.core.djangoapps.user_api.tests.test_helpers.FakeInputException' expected_log_msg = ( u"An unexpected error occurred when calling 'intercepted_function' with arguments '()' and " - u"keyword arguments '{'raise_error': }': FakeInputException()" - ) + u"keyword arguments '{{'raise_error': }}' " + u"from File \"{}\", line XXX, in test_logs_errors\n" + u" intercepted_function(raise_error=FakeInputException): FakeInputException()" + ).format(exception, __file__) # Verify that the raised exception has the error message try: intercepted_function(raise_error=FakeInputException) except FakeOutputException as ex: - self.assertEqual(ex.message, expected_log_msg) + actual_message = re.sub(r'line \d+', 'line XXX', ex.message, flags=re.MULTILINE) + self.assertEqual(actual_message, expected_log_msg) # Verify that the error logger is called # This will include the stack trace for the original exception # because it's called with log level "ERROR" - mock_logger.exception.assert_called_once_with(expected_log_msg) + calls = mock_logger.exception.mock_calls + self.assertEqual(len(calls), 1) + name, args, kwargs = calls[0] + + self.assertEqual(name, '') + self.assertEqual(len(args), 1) + self.assertEqual(kwargs, {}) + + actual_message = re.sub(r'line \d+', 'line XXX', args[0], flags=re.MULTILINE) + self.assertEqual(actual_message, expected_log_msg) class FormDescriptionTest(TestCase):