Skip to content

Commit

Permalink
Improvement to error handling
Browse files Browse the repository at this point in the history
Previously, if error occured during the creation of inner
type instance from iCalendar string, the error with the
name of the bogus property would be stored in the
appropriate component's errors attribute along with the error
string  but the property's value would be removed from the
parsed representation. This patch keeps the value even with its
parameters at that certain property, the value's type is changed
to vText.

Should allow implementation of
#158

Improves
#174
  • Loading branch information
stlaz authored and thet committed Oct 15, 2021
1 parent b225571 commit 97c2ce3
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 5 deletions.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ Breaking changes:
Refs #187
[stlaz]

- Improved error handling. The value and parameters of a property should no longer
be lost upon error.
Refs #158 #174
[stlaz]

New features:

- *add item here*
Expand Down
21 changes: 16 additions & 5 deletions src/icalendar/cal.py
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,17 @@ def from_ical(cls, st, multiple=False):
try:
factory = types_factory.for_property(name,
params.get('VALUE'))
if types_factory.is_list_property(name):
except ValueError as e:
if not component.ignore_exceptions:
raise
else:
# add error message and fall back to vText value type
component.errors.append((uname, str(e)))
factory = types_factory['text']
try:
if (types_factory.is_list_property(name) and
factory != vText):
# TODO: list type currenty supports only datetime types
vals = vDDDLists(
vDDDLists.from_ical(vals, params.get('TZID'),
factory))
Expand All @@ -399,10 +409,11 @@ def from_ical(cls, st, multiple=False):
if not component.ignore_exceptions:
raise
component.errors.append((uname, unicode_type(e)))
component.add(name, None, encode=0)
else:
vals.params = params
component.add(name, vals, encode=0)
# fallback to vText and store the original value
vals = types_factory['text'](vals)

vals.params = params
component.add(name, vals, encode=0)

if multiple:
return comps
Expand Down
11 changes: 11 additions & 0 deletions src/icalendar/tests/test_fixed_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -512,13 +512,17 @@ def test_issue_187(self):
event = icalendar.Event.from_ical('\r\n'.join(ical_str))
self.assertEqual(event.errors,
[('MYPROP', "Expected time, got: '20050520T200505'")])
self.assertEqual(event['MYPROP'],
icalendar.prop.vText('20050520T200505'))

# Wrong default property value (DATE instead of DATE-TIME)
ical_str = orig_str[:]
ical_str[2] = 'DTSTART:20150408'
event = icalendar.Event.from_ical('\r\n'.join(ical_str))
self.assertEqual(event.errors,
[('DTSTART', "Wrong datetime format '20150408'")])
self.assertEqual(event['DTSTART'],
icalendar.prop.vText('20150408'))

# -------- Wrong vDDDLists setups follow --------
ical_str = orig_str[:]
Expand All @@ -527,10 +531,17 @@ def test_issue_187(self):
event = icalendar.Event.from_ical('\r\n'.join(ical_str))
self.assertEqual(event.errors,
[('RDATE', "Wrong date format '20150217T095800'")])
self.assertEqual(event['RDATE'],
icalendar.prop.vText('20150217T095800'))

ical_str[3] = ('RDATE;FMTTYPE=text/plain;ENCODING=BASE64;VALUE=BINARY:'
'c3RsYXo=')
event = icalendar.Event.from_ical('\r\n'.join(ical_str))
self.assertEqual(event.errors,
[('RDATE', "The VALUE parameter of RDATE property "
"is not supported: 'BINARY'")])
self.assertEqual(event['RDATE'],
icalendar.prop.vText('c3RsYXo='))
self.assertEqual(event['RDATE'].params,
{'VALUE': 'BINARY', 'ENCODING': 'BASE64',
'FMTTYPE': 'text/plain'})

0 comments on commit 97c2ce3

Please sign in to comment.