Skip to content

Commit fcd49d6

Browse files
committed
Implemented an exceptions class for every kind of error.
1 parent 90e3913 commit fcd49d6

File tree

4 files changed

+56
-41
lines changed

4 files changed

+56
-41
lines changed

overpass/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,6 @@
88

99
from .api import API
1010
from .queries import MapQuery, WayQuery
11+
from .errors import (
12+
OverpassError, OverpassSyntaxError, TimeoutError, MultipleRequestsError, ServerLoadError, UnknownOverpassError
13+
)

overpass/api.py

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1-
import sys
21
import requests
32
import json
43
import geojson
54

5+
from .errors import OverpassSyntaxError, TimeoutError, MultipleRequestsError, ServerLoadError, UnknownOverpassError
6+
67

78
class API(object):
89
"""A simple Python wrapper for the OpenStreetMap Overpass API"""
@@ -40,20 +41,12 @@ def __init__(self, *args, **kwargs):
4041
def Get(self, query, asGeoJSON=False):
4142
"""Pass in an Overpass query in Overpass QL"""
4243

43-
response = ""
44+
full_query = self._ConstructQLQuery(query, asGeoJSON=asGeoJSON)
45+
raw_response = self._GetFromOverpass(full_query)
46+
response = json.loads(raw_response)
4447

45-
try:
46-
response = json.loads(self._GetFromOverpass(
47-
self._ConstructQLQuery(query, asGeoJSON=asGeoJSON)))
48-
except OverpassException as oe:
49-
print(oe)
50-
sys.exit(1)
51-
52-
if "elements" not in response or len(response["elements"]) == 0:
53-
raise OverpassException(
54-
204,
55-
'No OSM features satisfied your query'
56-
)
48+
if "elements" not in response:
49+
raise UnknownOverpassError("Received an invalid answer from Overpass.")
5750

5851
if not asGeoJSON:
5952
return response
@@ -63,7 +56,7 @@ def Get(self, query, asGeoJSON=False):
6356

6457
def Search(self, feature_type, regex=False):
6558
"""Search for something."""
66-
pass
59+
raise NotImplementedError()
6760

6861
def _ConstructQLQuery(self, userquery, asGeoJSON=False):
6962
raw_query = str(userquery)
@@ -96,23 +89,18 @@ def _GetFromOverpass(self, query):
9689
timeout=self.timeout
9790
)
9891
except requests.exceptions.Timeout:
99-
raise OverpassException(
100-
408,
101-
'Query timed out. API instance is set to time out in {timeout}'
102-
' seconds. Try passing in a higher value when instantiating'
103-
' this API: api = Overpass.API(timeout=60)'.format(
104-
timeout=self.timeout
105-
)
106-
)
92+
raise TimeoutError(self._timeout)
10793

10894
self._status = r.status_code
10995

11096
if self._status != 200:
11197
if self._status == 400:
112-
message = 'Query syntax error'
113-
else:
114-
message = 'Error from Overpass API'
115-
raise OverpassException(self._status, message)
98+
raise OverpassSyntaxError(query)
99+
elif self._status == 429:
100+
raise MultipleRequestsError()
101+
elif self._status == 504:
102+
raise ServerLoadError(self._timeout)
103+
raise UnknownOverpassError("The request returned status code {code}".format(code = self._status))
116104
else:
117105
return r.text
118106

@@ -139,15 +127,3 @@ def _asGeoJSON(self, elements):
139127
features.append(feature)
140128

141129
return geojson.FeatureCollection(features)
142-
143-
144-
class OverpassException(Exception):
145-
def __init__(self, status_code, message):
146-
self.status_code = status_code
147-
self.message = message
148-
149-
def __str__(self):
150-
return json.dumps({
151-
'status': self.status_code,
152-
'message': self.message
153-
})

overpass/errors.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
class OverpassError(Exception):
2+
"""An error during your request occurred. Super class for all Overpass api errors."""
3+
pass
4+
5+
6+
class OverpassSyntaxError(OverpassError, ValueError):
7+
"""The request contains a syntax error."""
8+
9+
def __init__(self, request):
10+
self.request = request
11+
12+
13+
class TimeoutError(OverpassError):
14+
"""A request timeout occurred."""
15+
16+
def __init__(self, timeout):
17+
self.timeout = timeout
18+
19+
20+
class MultipleRequestsError(OverpassError):
21+
"""You are trying to run multiple requests at the same time."""
22+
pass
23+
24+
25+
class ServerLoadError(OverpassError):
26+
"""The Overpass server is currently under load and declined the request. Try again later or retry with reduced
27+
timeout value."""
28+
29+
def __init__(self, timeout):
30+
self.timeout = timeout
31+
32+
33+
class UnknownOverpassError(OverpassError):
34+
"""An unknown kind of error happened during the request."""
35+
36+
def __init__(self, message):
37+
self.message = message

overpass/queries.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ def __str__(self):
2929

3030
class WayQuery(object):
3131

32-
"""Query to retrieve a set of ways and their dependent nodes satisfying
33-
the input parameters"""
32+
"""Query to retrieve a set of ways and their dependent nodes satisfying the input parameters"""
3433

3534
_QUERY_TEMPLATE = "(way{query_parameters});(._;>;);"
3635

0 commit comments

Comments
 (0)