This appears to be a bug in gpxpy
's error handling.
Looking at the source to parse
, when the parser fails without raising an exception, it tries to raise an exception with this:
raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(xml_or_file[0 : 100], parser.get_error()))
This assumes that xml_or_file
is an XML string—but, as the name implies, it's allowed to be either a string or a file object. So, what you're doing (giving it a file object) is perfectly legal and should work, and it doesn't, and therefore it's a bug.
So, you should file an issue. The correct patch should be something like:
if not parser.is_valid():
try:
fragment = xml_or_file[0 : 100]
except TypeError:
xml_or_file.seek(0)
fragment = xml_or_file.read(100)
raise mod_gpx.GPXException('Error parsing {0}: {1}'.format(fragment, parser.get_error()))
So, how do you work around this? A few options:
Since it only happens with invalid files anyway, you can just use
except Exception
orexcept (gpxpy.gpx.GPXException, TypeError)
.Since it only happens when you give it a the file object, give it a string instead:
gpx = gpx.parse(file.read())
. This is a bad idea if the file is very large, of course.Since the buggy function is only 12 lines of trivial code wrapping the real function, just use the real function directly. Or, if you like the wrapper, copy it, fix it, and use your own copy instead.
Meanwhile, given that the very first bit of code I looked at in this library has some obvious red flags (Why xml_or_file[0 : 100]
instead of just xml_or_file[:100]
? Why catch exceptions, throw them away and just set a flag, and then use that flag to raise a new exception with all the information missing?), if you're not able to debug libraries on your own, I don't think this one is ready for you to use.