Skip to content

Commit d5ad27b

Browse files
Improve EDTFParseException handling
Includes handling for empty or null input strings and null errs passed to the constructor Co-Authored-By: aweakley <224316+aweakley@users.noreply.github.com>
1 parent 55b0723 commit d5ad27b

3 files changed

Lines changed: 35 additions & 11 deletions

File tree

edtf/fields.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
from django.db import models
55
from django.db.models import signals
66
from django.db.models.query_utils import DeferredAttribute
7+
from pyparsing import ParseException
78

89
from edtf import EDTFObject, parse_edtf
910
from edtf.convert import struct_time_to_date, struct_time_to_jd
1011
from edtf.natlang import text_to_edtf
12+
from edtf.parser.edtf_exceptions import EDTFParseException
1113

1214
DATE_ATTRS = (
1315
"lower_strict",
@@ -132,10 +134,12 @@ def update_values(self, instance, *args, **kwargs):
132134
if direct_input and (
133135
existing_value is None or str(existing_value) != direct_input
134136
):
135-
edtf = parse_edtf(
136-
direct_input, fail_silently=True
137-
) # ParseException if invalid; should this be raised?
138-
# TODO pyparsing.ParseExceptions are very noisy and dumps the whole grammar (see https://github.com/ixc/python-edtf/issues/46)
137+
try:
138+
edtf = parse_edtf(
139+
direct_input, fail_silently=True
140+
) # ParseException if invalid; should this be raised?
141+
except ParseException as err:
142+
raise EDTFParseException(direct_input, err) from None
139143

140144
# set the natural_text (display) field to the direct_input if it is not provided
141145
if natural_text == "":

edtf/parser/edtf_exceptions.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,28 @@
22

33

44
class EDTFParseException(ParseException):
5-
pass
5+
"""Raised when an input cannot be parsed as an EDTF string.
6+
7+
Attributes:
8+
input_string - the input string that could not be parsed
9+
err -- the original ParseException that caused this one
10+
"""
11+
12+
def __init__(self, input_string, err=None):
13+
if input_string is None:
14+
input_string = ""
15+
self.input_string = input_string
16+
if err is None:
17+
err = ParseException(input_string, 0, "Invalid input or format.")
18+
self.err = err
19+
super().__init__(str(err), err.loc if err.loc else 0, self.input_string)
20+
21+
def __str__(self):
22+
if not self.input_string:
23+
return "You must supply some input text"
24+
near_text = (
25+
self.input_string[max(self.err.loc - 10, 0) : self.err.loc + 10]
26+
if hasattr(self.err, "loc")
27+
else ""
28+
)
29+
return f"Error at position {self.err.loc}: Invalid input or format near '{near_text}'. Please provide a valid EDTF string."

edtf/parser/grammar.py

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,7 @@ def parse_edtf(input_string, parseAll=True, fail_silently=False, debug=None):
347347
if debug is None:
348348
debug = DEBUG_PYPARSING
349349
if not input_string:
350-
raise EDTFParseException("You must supply some input text")
350+
raise EDTFParseException(input_string)
351351
try:
352352
p = edtfParser.parseString(input_string.strip(), parseAll)
353353
if p:
@@ -357,8 +357,4 @@ def parse_edtf(input_string, parseAll=True, fail_silently=False, debug=None):
357357
return None
358358
if debug:
359359
raise
360-
near_text = ""
361-
if input_string:
362-
near_text = input_string[max(err.loc - 10, 0) : err.loc + 10]
363-
full_msg = f"Error at position {err.loc}: Invalid input or format near '{near_text}'. Please provide a valid EDTF string."
364-
raise EDTFParseException(full_msg) from None
360+
raise EDTFParseException(input_string, err) from None

0 commit comments

Comments
 (0)