question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

API: custom classes for GEOS exceptions

See original GitHub issue

Moving an inline discussion to its separate dedicated issue: https://github.com/Toblerity/Shapely/pull/983#discussion_r489285146

Currently, Shapely has a few custom error classes, such as TopologicalError. Using an example from the tests:

from shapely.geometry import Polygon
p1 = [(339, 346), (459,346), (399,311), (340, 277), (399, 173),
      (280, 242), (339, 415), (280, 381), (460, 207), (339, 346)]
p2 = [(339, 207), (280, 311), (460, 138), (399, 242), (459, 277),
      (459, 415), (399, 381), (519, 311), (520, 242), (519, 173),
      (399, 450), (339, 207)]

>>> Polygon(p1).within(Polygon(p2))
TopologyException: side location conflict at 459 346
Traceback (most recent call last):
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/predicates.py", line 15, in __call__
    return self.fn(this._geom, other._geom, *args)
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/geos.py", line 580, in errcheck_predicate
    raise PredicateError("Failed to evaluate %s" % repr(func))
shapely.errors.PredicateError: Failed to evaluate <_FuncPtr object at 0x7f0a641ce1c0>

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/geometry/base.py", line 752, in within
    return bool(self.impl['within'](self, other))
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/predicates.py", line 18, in __call__
    self._check_topology(err, this, other)
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/topology.py", line 35, in _check_topology
    raise TopologicalError(
shapely.errors.TopologicalError: The operation 'GEOSWithin_r' could not be performed. Likely cause is invalidity of the geometry <shapely.geometry.polygon.Polygon object at 0x7f0a6488e490>

So you can see that here a custom TopologicalError exception class is used with a general message about geometries likely being invalid, but the original GEOS error message is also still printed at the beginning of the stacktrace.

Using pygeos on the same example:

>>> import pygeos
>>> p1 = pygeos.polygons(p1)
>>> p2 = pygeos.polygons(p2)
>>> pygeos.within(p1, p2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/pygeos/decorators.py", line 55, in wrapped
    return func(*args, **kwargs)
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/pygeos/predicates.py", line 653, in within
    return lib.within(a, b, **kwargs)
pygeos.GEOSException: TopologyException: side location conflict at 459 346

Here, pygeos currently uses a generic GEOSException class for all exceptions raised directly by GEOS, and then adds the specific error message from GEOS.


So for Shapely 2.0 when moving in pygeos’ code (started in #983), we need to decide if we are fine with the current approach in pygeos or if we want to extend it to be more like current Shapely’s behaviour.

Personally, I am fine with the approach of pygeos: the error message already indicates it is a Topology related error, so I am not sure a custom exception class gives that much added value.

cc @caspervdw @sgillies @mwtoews @brendan-ward

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:13 (11 by maintainers)

github_iconTop GitHub Comments

1reaction
brendan-wardcommented, Sep 28, 2020

Custom exception classes add value where it is possible to programmatically catch and then respond to them as separate categories or where they add clarity / context to the emitted exception. I’m not seeing much of either case here, so in my opinion, it seems OK to deprecate these.

For topology errors, every time I’ve hit those, it required manual intervention and some custom workaround - so I wouldn’t want to catch and handle this automatically, as distinct from other exceptions.

For WKT errors, the pygeos stacktrace makes it clear that it is coming from from_wkt call, so it doesn’t seem like WKTReadingError adds much additional context there. Again, this is one that would require manual inspection and correction rather than being automatically handled.

Some of the other custom errors don’t seem like they need to be custom errors. Some seem like ValueError if caught during validation here rather than in GEOS (e.g., DimensionError), others seem like ImportError or RuntimeError (e.g., UnsupportedGEOSVersionError).

1reaction
jorisvandenbosschecommented, Sep 25, 2020

And to give an example of where Shapely has another custom exception class: parsing WKB/WKT.

>>> from shapely.wkt import loads
>>> loads("nonsense")
ParseException: Unknown type: 'NONSENSE'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/wkt.py", line 10, in loads
    return geos.WKTReader(geos.lgeos).read(data)
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/shapely/geos.py", line 285, in read
    raise WKTReadingError(
shapely.errors.WKTReadingError: Could not create geometry because of errors while reading input.

vs

>>> import pygeos
>>> pygeos.from_wkt("nonsense")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/joris/miniconda3/envs/DS-python-geospatial/lib/python3.8/site-packages/pygeos/io.py", line 160, in from_wkt
    return lib.from_wkt(geometry, **kwargs)
pygeos.GEOSException: ParseException: Unknown type: 'NONSENSE'
Read more comments on GitHub >

github_iconTop Results From Across the Web

API: custom classes for GEOS exceptions · Issue #991 - GitHub
Here, pygeos currently uses a generic GEOSException class for all exceptions raised directly by GEOS, and then adds the specific error message ...
Read more >
Custom Error Message Handling for REST API - Baeldung
In this tutorial, we'll discuss how to implement a global error handler for a Spring REST API. We will use the semantics of...
Read more >
Writing a Custom Geo Location Provider - WSO2 API Manager ...
For example, the following class is a sample implementation of the Geolocation Resolving service It returns the Location according to the IP of...
Read more >
Add Geo Target | Google Ads API
Adds a geo target to an extension feed item for targeting. */ ... GoogleAdsException is the base class for most exceptions thrown by...
Read more >
arcgis.features module | ArcGIS API for Python
Features are stored as feature classes, which represent a set of features located using a single spatial type (point, line, polygon) and a...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found