def component_handler(request, usage_key_string, handler, suffix=''): """ Dispatch an AJAX action to an xblock Args: usage_id: The usage-id of the block to dispatch to handler (str): The handler to execute suffix (str): The remainder of the url to be passed to the handler Returns: :class:`django.http.HttpResponse`: The response from the handler, converted to a django response """ usage_key = UsageKey.from_string(usage_key_string) descriptor = modulestore().get_item(usage_key) descriptor.xmodule_runtime = StudioEditModuleRuntime(request.user) # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = descriptor.handle(handler, req, suffix) except NoSuchHandlerError: log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True) raise Http404 # unintentional update to handle any side effects of handle call # could potentially be updating actual course data or simply caching its values modulestore().update_item(descriptor, request.user.id) return webob_to_django_response(resp)
def component_handler(request, usage_id, handler, suffix=""): """ Dispatch an AJAX action to an xblock Args: usage_id: The usage-id of the block to dispatch to, passed through `quote_slashes` handler (str): The handler to execute suffix (str): The remainder of the url to be passed to the handler Returns: :class:`django.http.HttpResponse`: The response from the handler, converted to a django response """ location = unquote_slashes(usage_id) descriptor = modulestore().get_item(location) # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = descriptor.handle(handler, req, suffix) except NoSuchHandlerError: log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True) raise Http404 modulestore().save_xmodule(descriptor) return webob_to_django_response(resp)
def preview_handler(request, usage_key_string, handler, suffix=''): """ Dispatch an AJAX action to an xblock usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes` handler: The handler to execute suffix: The remainder of the url to be passed to the handler """ usage_key = UsageKey.from_string(usage_key_string) descriptor = modulestore().get_item(usage_key) instance = _load_preview_module(request, descriptor) # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 except ProcessingError: log.warning("Module raised an error while processing AJAX request", exc_info=True) return HttpResponseBadRequest() except Exception: log.exception("error processing ajax call") raise return webob_to_django_response(resp)
def component_handler(request, usage_key_string, handler, suffix=''): """ Dispatch an AJAX action to an xblock Args: usage_id: The usage-id of the block to dispatch to handler (str): The handler to execute suffix (str): The remainder of the url to be passed to the handler Returns: :class:`django.http.HttpResponse`: The response from the handler, converted to a django response """ usage_key = UsageKey.from_string(usage_key_string) descriptor = get_modulestore(usage_key).get_item(usage_key) # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = descriptor.handle(handler, req, suffix) except NoSuchHandlerError: log.info("XBlock %s attempted to access missing handler %r", descriptor, handler, exc_info=True) raise Http404 # unintentional update to handle any side effects of handle call; so, request user didn't author # the change get_modulestore(usage_key).update_item(descriptor, None) return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({"success": error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format(course_id=course_id, location=location) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents(course_id, user, descriptor) instance = get_module(user, request, location, field_data_cache, course_id, grade_bucket_type="ajax") if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={"success": err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def test_post_already_read(self): # Check that POST already having been read from doesn't # prevent access to the POST of the webob object dj_req = self.req_factory.post('dummy_url', data={'foo': 'bar'}) # Read from POST before constructing the webob request self.assertEqual(dj_req.POST.getlist('foo'), ['bar']) # pylint: disable=no-member webob_req = django_to_webob_request(dj_req) self.assertEqual(webob_req.POST.getall('foo'), ['bar'])
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked """ # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return JsonResponse(object={'success': error_msg}, status=413) instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id) # Name the transaction so that we can view XBlock handlers separately in # New Relic. The suffix is necessary for XModule handlers because the # "handler" in those cases is always just "xmodule_handler". nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler) nr_tx_name += "/{}".format(suffix) if suffix else "" newrelic.agent.set_transaction_name(nr_tx_name, group="Python/XBlock/Handler") tracking_context_name = 'module_callback_handler' req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def handler(request, usage_id, handler_slug): """Provide a handler for the request.""" student_id = get_student_id(request) log.info("Start handler %s/%s for student %s", usage_id, handler_slug, student_id) runtime = WorkbenchRuntime(student_id) block = runtime.get_block(usage_id) request = django_to_webob_request(request) request.path_info_pop() request.path_info_pop() result = block.runtime.handle(block, handler_slug, request) log.info("End handler %s/%s", usage_id, handler_slug) return webob_to_django_response(result)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked """ # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return JsonResponse(object={'success': error_msg}, status=413) instance, tracking_context = _get_module_by_usage_id(request, course_id, usage_id) tracking_context_name = 'module_callback_handler' req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def preview_handler(request, usage_key_string, handler, suffix=""): """ Dispatch an AJAX action to an xblock usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes` handler: The handler to execute suffix: The remainder of the url to be passed to the handler """ usage_key = UsageKey.from_string(usage_key_string) if isinstance(usage_key, AsideUsageKeyV1): descriptor = modulestore().get_item(usage_key.usage_key) for aside in descriptor.runtime.get_asides(descriptor): if aside.scope_ids.block_type == usage_key.aside_type: asides = [aside] instance = aside break else: descriptor = modulestore().get_item(usage_key) instance = _load_preview_module(request, descriptor) asides = [] # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 except ProcessingError: log.warning("Module raised an error while processing AJAX request", exc_info=True) return HttpResponseBadRequest() except Exception: log.exception("error processing ajax call") raise modulestore().update_item(descriptor, request.user.id, asides=asides) return webob_to_django_response(resp)
def handler(request, usage_id, handler_slug, suffix='', authenticated=True): """The view function for authenticated handler requests.""" if authenticated: student_id = get_student_id(request) log.info("Start handler %s/%s for student %s", usage_id, handler_slug, student_id) else: student_id = "none" log.info("Start handler %s/%s", usage_id, handler_slug) runtime = WorkbenchRuntime(student_id) try: block = runtime.get_block(usage_id) except NoSuchUsage: raise Http404 request = django_to_webob_request(request) request.path_info_pop() request.path_info_pop() result = block.runtime.handle(block, handler_slug, request, suffix) log.info("End handler %s/%s", usage_id, handler_slug) return webob_to_django_response(result)
def preview_handler(request, usage_key_string, handler, suffix=''): """ Dispatch an AJAX action to an xblock usage_key_string: The usage_key_string-id of the block to dispatch to, passed through `quote_slashes` handler: The handler to execute suffix: The remainder of the url to be passed to the handler """ usage_key = UsageKey.from_string(usage_key_string) descriptor = modulestore().get_item(usage_key) instance = _load_preview_module(request, descriptor) # Let the module handle the AJAX req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception(u"XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 except ProcessingError: log.warning("Module raised an error while processing AJAX request", exc_info=True) return HttpResponseBadRequest() except Exception: log.exception("error processing ajax call") raise return webob_to_django_response(resp)
def handle_xblock_callback(request, course_id, usage_id, handler, suffix=None): """ Generic view for extensions. This is where AJAX calls go. Arguments: - request -- the django request. - location -- the module location. Used to look up the XModule instance - course_id -- defines the course context for this request. Raises PermissionDenied if the user is not logged in. Raises Http404 if the location and course_id do not identify a valid module, the module is not accessible by the user, or the module raises NotFoundError. If the module raises any other error, it will escape this function. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") if not request.user.is_authenticated(): raise PermissionDenied # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location ) ) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, request.user, descriptor ) instance = get_module(request.user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, request.user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. """ location = unquote_slashes(usage_id) # Check parameters and fail fast if there's a problem if not Location.is_valid(location): raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_instance(course_id, location) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {location}".format( course_id=course_id, location=location)) raise Http404 field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor) instance = get_module(user, request, location, field_data_cache, course_id, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", location, user) raise Http404 req = django_to_webob_request(request) try: resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course=None): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked """ # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return JsonResponse({'success': error_msg}, status=413) # Make a CourseKey from the course_id, raising a 404 upon parse error. try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: raise Http404 set_custom_metrics_for_course_key(course_key) with modulestore().bulk_operations(course_key): instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id, course=course) # Name the transaction so that we can view XBlock handlers separately in # New Relic. The suffix is necessary for XModule handlers because the # "handler" in those cases is always just "xmodule_handler". nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler) nr_tx_name += "/{}".format(suffix) if (suffix and handler == "xmodule_handler") else "" set_monitoring_transaction_name(nr_tx_name, group="Python/XBlock/Handler") tracking_context_name = 'module_callback_handler' req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) if suffix == 'problem_check' \ and course \ and getattr(course, 'entrance_exam_enabled', False) \ and getattr(instance, 'in_entrance_exam', False): ee_data = {'entrance_exam_passed': user_has_passed_entrance_exam(request.user, course)} resp = append_data_to_webob_response(resp, ee_data) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse({'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked user (User): The currently logged in user """ try: course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) usage_key = course_id.make_usage_key_from_deprecated_string( unquote_slashes(usage_id)) except InvalidKeyError: raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_item(usage_key) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {usage_key}".format( course_id=usage_key.course_key, usage_key=usage_key)) raise Http404 tracking_context_name = 'module_callback_handler' tracking_context = { 'module': { 'display_name': descriptor.display_name_with_default, } } field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor) instance = get_module(user, request, usage_key, field_data_cache, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", usage_key, user) raise Http404 req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def handle(self, block, handler_name, request, suffix=''): # Convert Django request to webob request = django_to_webob_request(request) return super(Runtime, self).handle(block, handler_name, request, suffix=suffix)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, course=None): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked """ # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return JsonResponse({'success': error_msg}, status=413) # Make a CourseKey from the course_id, raising a 404 upon parse error. try: course_key = CourseKey.from_string(course_id) except InvalidKeyError: raise Http404 # Gather metrics for New Relic so we can slice data in New Relic Insights newrelic.agent.add_custom_parameter('course_id', unicode(course_key)) newrelic.agent.add_custom_parameter('org', unicode(course_key.org)) with modulestore().bulk_operations(course_key): instance, tracking_context = get_module_by_usage_id(request, course_id, usage_id, course=course) # Name the transaction so that we can view XBlock handlers separately in # New Relic. The suffix is necessary for XModule handlers because the # "handler" in those cases is always just "xmodule_handler". nr_tx_name = "{}.{}".format(instance.__class__.__name__, handler) nr_tx_name += "/{}".format(suffix) if (suffix and handler == "xmodule_handler") else "" newrelic.agent.set_transaction_name(nr_tx_name, group="Python/XBlock/Handler") tracking_context_name = 'module_callback_handler' req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) if suffix == 'problem_check' \ and course \ and getattr(course, 'entrance_exam_enabled', False) \ and getattr(instance, 'in_entrance_exam', False): ee_data = {'entrance_exam_passed': user_has_passed_entrance_exam(request, course)} resp = append_data_to_webob_response(resp, ee_data) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse({'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)
def _invoke_xblock_handler(request, course_id, usage_id, handler, suffix, user): """ Invoke an XBlock handler, either authenticated or not. Arguments: request (HttpRequest): the current request course_id (str): A string of the form org/course/run usage_id (str): A string of the form i4x://org/course/category/name@revision handler (str): The name of the handler to invoke suffix (str): The suffix to pass to the handler when invoked user (User): The currently logged in user """ try: course_id = SlashSeparatedCourseKey.from_deprecated_string(course_id) usage_key = course_id.make_usage_key_from_deprecated_string(unquote_slashes(usage_id)) except InvalidKeyError: raise Http404("Invalid location") # Check submitted files files = request.FILES or {} error_msg = _check_files_limits(files) if error_msg: return HttpResponse(json.dumps({'success': error_msg})) try: descriptor = modulestore().get_item(usage_key) except ItemNotFoundError: log.warn( "Invalid location for course id {course_id}: {usage_key}".format( course_id=usage_key.course_key, usage_key=usage_key ) ) raise Http404 tracking_context_name = 'module_callback_handler' tracking_context = { 'module': { 'display_name': descriptor.display_name_with_default, } } field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, descriptor ) instance = get_module(user, request, usage_key, field_data_cache, grade_bucket_type='ajax') if instance is None: # Either permissions just changed, or someone is trying to be clever # and load something they shouldn't have access to. log.debug("No module %s for user %s -- access denied?", usage_key, user) raise Http404 req = django_to_webob_request(request) try: with tracker.get_tracker().context(tracking_context_name, tracking_context): resp = instance.handle(handler, req, suffix) except NoSuchHandlerError: log.exception("XBlock %s attempted to access missing handler %r", instance, handler) raise Http404 # If we can't find the module, respond with a 404 except NotFoundError: log.exception("Module indicating to user that request doesn't exist") raise Http404 # For XModule-specific errors, we log the error and respond with an error message except ProcessingError as err: log.warning("Module encountered an error while processing AJAX call", exc_info=True) return JsonResponse(object={'success': err.args[0]}, status=200) # If any other error occurred, re-raise it to trigger a 500 response except Exception: log.exception("error executing xblock handler") raise return webob_to_django_response(resp)