Skip to content

Commit

Permalink
Improve EDTFParseException handling
Browse files Browse the repository at this point in the history
Includes handling for empty or null input strings and null errs passed to the constructor

Co-Authored-By: aweakley <[email protected]>
  • Loading branch information
ColeDCrawford and aweakley committed Jun 3, 2024
1 parent 55b0723 commit d5ad27b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 11 deletions.
12 changes: 8 additions & 4 deletions edtf/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
from django.db import models
from django.db.models import signals
from django.db.models.query_utils import DeferredAttribute
from pyparsing import ParseException

from edtf import EDTFObject, parse_edtf
from edtf.convert import struct_time_to_date, struct_time_to_jd
from edtf.natlang import text_to_edtf
from edtf.parser.edtf_exceptions import EDTFParseException

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

# set the natural_text (display) field to the direct_input if it is not provided
if natural_text == "":
Expand Down
26 changes: 25 additions & 1 deletion edtf/parser/edtf_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,28 @@


class EDTFParseException(ParseException):
pass
"""Raised when an input cannot be parsed as an EDTF string.
Attributes:
input_string - the input string that could not be parsed
err -- the original ParseException that caused this one
"""

def __init__(self, input_string, err=None):
if input_string is None:
input_string = ""
self.input_string = input_string
if err is None:
err = ParseException(input_string, 0, "Invalid input or format.")
self.err = err
super().__init__(str(err), err.loc if err.loc else 0, self.input_string)

def __str__(self):
if not self.input_string:
return "You must supply some input text"
near_text = (
self.input_string[max(self.err.loc - 10, 0) : self.err.loc + 10]
if hasattr(self.err, "loc")
else ""
)
return f"Error at position {self.err.loc}: Invalid input or format near '{near_text}'. Please provide a valid EDTF string."
8 changes: 2 additions & 6 deletions edtf/parser/grammar.py
Original file line number Diff line number Diff line change
Expand Up @@ -347,7 +347,7 @@ def parse_edtf(input_string, parseAll=True, fail_silently=False, debug=None):
if debug is None:
debug = DEBUG_PYPARSING
if not input_string:
raise EDTFParseException("You must supply some input text")
raise EDTFParseException(input_string)
try:
p = edtfParser.parseString(input_string.strip(), parseAll)
if p:
Expand All @@ -357,8 +357,4 @@ def parse_edtf(input_string, parseAll=True, fail_silently=False, debug=None):
return None
if debug:
raise
near_text = ""
if input_string:
near_text = input_string[max(err.loc - 10, 0) : err.loc + 10]
full_msg = f"Error at position {err.loc}: Invalid input or format near '{near_text}'. Please provide a valid EDTF string."
raise EDTFParseException(full_msg) from None
raise EDTFParseException(input_string, err) from None

0 comments on commit d5ad27b

Please sign in to comment.