Commit 0b1efc15 by Braden MacDonald

Fix exception when ID is malformed, add validation warning

parent 0ef235eb
...@@ -37,7 +37,6 @@ from .sub_api import sub_api ...@@ -37,7 +37,6 @@ from .sub_api import sub_api
from lazy import lazy from lazy import lazy
from webob import Response from webob import Response
from xblock.core import XBlock from xblock.core import XBlock
from xblock.exceptions import XBlockNotFoundError
from xblock.fields import Scope, List, String from xblock.fields import Scope, List, String
from xblock.fragment import Fragment from xblock.fragment import Fragment
from xblock.validation import ValidationMessage from xblock.validation import ValidationMessage
...@@ -149,6 +148,11 @@ class ColorRule(object): ...@@ -149,6 +148,11 @@ class ColorRule(object):
return eval_(expr) return eval_(expr)
class InvalidUrlName(ValueError):
""" Exception raised by DashboardBlock.get_mentoring_blocks() if a url_name is invalid """
pass
@XBlock.needs("i18n") @XBlock.needs("i18n")
class DashboardBlock(StudioEditableXBlockMixin, XBlock): class DashboardBlock(StudioEditableXBlockMixin, XBlock):
""" """
...@@ -192,24 +196,27 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock): ...@@ -192,24 +196,27 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
editable_fields = ('display_name', 'mentoring_ids', 'color_rules', 'visual_rules') editable_fields = ('display_name', 'mentoring_ids', 'color_rules', 'visual_rules')
css_path = 'public/css/dashboard.css' css_path = 'public/css/dashboard.css'
def get_mentoring_blocks(self): def get_mentoring_blocks(self, mentoring_ids, ignore_errors=True):
""" """
Generator returning the specified mentoring blocks, in order. Generator returning the specified mentoring blocks, in order.
Returns a list. Will insert None for every invalid mentoring block ID. Returns a list. Will insert None for every invalid mentoring block ID, or if
ignore_errors is False, will raise InvalidUrlName.
""" """
for url_name in self.mentoring_ids: for url_name in mentoring_ids:
mentoring_id = self.scope_ids.usage_id.course_key.make_usage_key('problem-builder', url_name)
try: try:
mentoring_id = self.scope_ids.usage_id.course_key.make_usage_key('problem-builder', url_name)
yield self.runtime.get_block(mentoring_id) yield self.runtime.get_block(mentoring_id)
# Catch all here b/c edX runtime throws other exceptions we can't import in other contexts like workbench: except Exception: # Catch-all b/c we could get XBlockNotFoundError, ItemNotFoundError, InvalidKeyError, ...
except (XBlockNotFoundError, Exception):
# Maybe it's using the deprecated block type "mentoring": # Maybe it's using the deprecated block type "mentoring":
mentoring_id = self.scope_ids.usage_id.course_key.make_usage_key('mentoring', url_name)
try: try:
mentoring_id = self.scope_ids.usage_id.course_key.make_usage_key('mentoring', url_name)
yield self.runtime.get_block(mentoring_id) yield self.runtime.get_block(mentoring_id)
except (XBlockNotFoundError, Exception): except Exception:
yield None if ignore_errors:
yield None
else:
raise InvalidUrlName(url_name)
def parse_color_rules_str(self, color_rules_str, ignore_errors=True): def parse_color_rules_str(self, color_rules_str, ignore_errors=True):
""" """
...@@ -275,7 +282,7 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock): ...@@ -275,7 +282,7 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
Create the HTML for this block, by getting the data and inserting it into a template. Create the HTML for this block, by getting the data and inserting it into a template.
""" """
blocks = [] blocks = []
for mentoring_block in self.get_mentoring_blocks(): for mentoring_block in self.get_mentoring_blocks(self.mentoring_ids):
if mentoring_block is None: if mentoring_block is None:
continue continue
block = { block = {
...@@ -357,6 +364,11 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock): ...@@ -357,6 +364,11 @@ class DashboardBlock(StudioEditableXBlockMixin, XBlock):
def add_error(msg): def add_error(msg):
validation.add(ValidationMessage(ValidationMessage.ERROR, msg)) validation.add(ValidationMessage(ValidationMessage.ERROR, msg))
try:
list(self.get_mentoring_blocks(data.mentoring_ids, ignore_errors=False))
except InvalidUrlName as e:
add_error(_(u'Invalid block url_name given: "{bad_url_name}"').format(bad_url_name=unicode(e)))
if data.color_rules: if data.color_rules:
try: try:
self.parse_color_rules_str(data.color_rules, ignore_errors=False) self.parse_color_rules_str(data.color_rules, ignore_errors=False)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment