Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions overpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,22 @@ def __init__(self, read_chunk_size=None, url=None, xml_parser=XML_PARSER_SAX, ma

self.xml_parser = xml_parser

def _handle_remark_msg(self, msg):
"""
Try to parse the message provided with the remark tag or element.

:param str msg: The message
:raises overpy.exception.OverpassRuntimeError: If message starts with 'runtime error:'
:raises overpy.exception.OverpassRuntimeRemark: If message starts with 'runtime remark:'
:raises overpy.exception.OverpassUnknownError: If we are unable to identify the error
"""
msg = msg.strip()
if msg.startswith("runtime error:"):
raise exception.OverpassRuntimeError(msg=msg)
elif msg.startswith("runtime remark:"):
raise exception.OverpassRuntimeRemark(msg=msg)
raise exception.OverpassUnknownError(msg=msg)

def query(self, query):
"""
Query the Overpass API
Expand Down Expand Up @@ -189,6 +205,8 @@ def parse_json(self, data, encoding="utf-8"):
if isinstance(data, bytes):
data = data.decode(encoding)
data = json.loads(data, parse_float=Decimal)
if "remark" in data:
self._handle_remark_msg(msg=data.get("remark"))
return Result.from_json(data, api=self)

def parse_xml(self, data, encoding="utf-8", parser=None):
Expand All @@ -210,6 +228,10 @@ def parse_xml(self, data, encoding="utf-8", parser=None):
# Python 2.x: Convert unicode strings
data = data.encode(encoding)

m = re.compile("<remark>(?P<msg>[^<>]*)</remark>").search(data)
if m:
self._handle_remark_msg(m.group("msg"))

return Result.from_xml(data, api=self, parser=parser)


Expand Down
46 changes: 46 additions & 0 deletions overpy/exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,29 @@ def __str__(self):
return "\n".join(tmp_msgs)


class OverpassError(OverPyException):
"""
Base exception to report errors if the response returns a remark tag or element.

.. note::
If you are not sure which of the subexceptions you should use, use this one and try to parse the message.

For more information have a look at https://github.com/DinoTools/python-overpy/issues/62

:param str msg: The message from the remark tag or element
"""
def __init__(self, msg=None):
#: The message from the remark tag or element
self.msg = msg

def __str__(self):
if self.msg is None:
return "No error message provided"
if not isinstance(self.msg, str):
return str(self.msg)
return self.msg


class OverpassGatewayTimeout(OverPyException):
"""
Raised if load of the Overpass API service is too high and it can't handle the request.
Expand All @@ -82,6 +105,22 @@ def __init__(self):
OverPyException.__init__(self, "Server load too high")


class OverpassRuntimeError(OverpassError):
"""
Raised if the server returns a remark-tag(xml) or remark element(json) with a message starting with
'runtime error:'.
"""
pass


class OverpassRuntimeRemark(OverpassError):
"""
Raised if the server returns a remark-tag(xml) or remark element(json) with a message starting with
'runtime remark:'.
"""
pass


class OverpassTooManyRequests(OverPyException):
"""
Raised if the Overpass API service returns a 429 status code.
Expand All @@ -106,6 +145,13 @@ def __str__(self):
return "Unknown content type: %s" % self.content_type


class OverpassUnknownError(OverpassError):
"""
Raised if the server returns a remark-tag(xml) or remark element(json) and we are unable to find any reason.
"""
pass


class OverpassUnknownHTTPStatusCode(OverPyException):
"""
Raised if the returned HTTP status code isn't handled by OverPy.
Expand Down
15 changes: 15 additions & 0 deletions tests/json/remark-runtime-error-01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": 0.6,
"generator": "Overpass API",
"osm3s": {
"timestamp_osm_base": "2017-03-17T22:05:02Z",
"timestamp_areas_base": "2017-03-17T18:38:02Z",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
},
"elements": [



],
"remark": "runtime error: Query timed out in \"query\" at line 4 after 2 seconds."
}
15 changes: 15 additions & 0 deletions tests/json/remark-runtime-remark-01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": 0.6,
"generator": "Overpass API",
"osm3s": {
"timestamp_osm_base": "2017-03-17T22:05:02Z",
"timestamp_areas_base": "2017-03-17T18:38:02Z",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
},
"elements": [



],
"remark": "runtime remark: Test"
}
15 changes: 15 additions & 0 deletions tests/json/remark-unknown-01.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"version": 0.6,
"generator": "Overpass API",
"osm3s": {
"timestamp_osm_base": "2017-03-17T22:05:02Z",
"timestamp_areas_base": "2017-03-17T18:38:02Z",
"copyright": "The data included in this document is from www.openstreetmap.org. The data is made available under ODbL."
},
"elements": [



],
"remark": "Test remark"
}
24 changes: 23 additions & 1 deletion tests/test_exception.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,26 @@ def test_overpass_unknown_content_type(self):
def test_overpass_unknown_http_status_code(self):
e = overpy.exception.OverpassUnknownHTTPStatusCode(123)
assert e.code == 123
assert str(e).endswith("123")
assert str(e).endswith("123")

def test_overpass_error(self):
exceptions = [
overpy.exception.OverpassError,
overpy.exception.OverpassRuntimeError,
overpy.exception.OverpassRuntimeRemark,
overpy.exception.OverpassUnknownError
]
for cls in exceptions:
e = cls(msg="Test message")
assert e.msg == "Test message"
assert str(e) == "Test message"

for cls in exceptions:
e = cls()
assert e.msg is None
assert str(e) == "No error message provided"

for cls in exceptions:
e = cls(msg=123)
assert e.msg == 123
assert str(e) == "123"
19 changes: 18 additions & 1 deletion tests/test_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,21 @@ def test_element_wrong_type(self):
{
"type": "foo"
}
)
)


class TestRemark(object):
def test_remark_runtime_error(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassRuntimeError):
api.parse_json(read_file("json/remark-runtime-error-01.json"))

def test_remark_runtime_remark(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassRuntimeRemark):
api.parse_json(read_file("json/remark-runtime-remark-01.json"))

def test_remark_unknown(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassUnknownError):
api.parse_json(read_file("json/remark-unknown-01.json"))
17 changes: 17 additions & 0 deletions tests/test_xml.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,20 @@ def test_way_missing_data(self):
node = ET.fromstring(data)
with pytest.raises(ValueError):
overpy.Way.from_xml(node)


class TestRemark(object):
def test_remark_runtime_error(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassRuntimeError):
api.parse_xml(read_file("xml/remark-runtime-error-01.xml"))

def test_remark_runtime_remark(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassRuntimeRemark):
api.parse_xml(read_file("xml/remark-runtime-remark-01.xml"))

def test_remark_unknown(self):
api = overpy.Overpass()
with pytest.raises(overpy.exception.OverpassUnknownError):
api.parse_xml(read_file("xml/remark-unknown-01.xml"))
8 changes: 8 additions & 0 deletions tests/xml/remark-runtime-error-01.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2017-03-17T22:03:02Z" areas="2017-03-17T18:38:02Z"/>

<remark> runtime error: Query timed out in "query" at line 4 after 2 seconds. </remark>

</osm>
8 changes: 8 additions & 0 deletions tests/xml/remark-runtime-remark-01.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2017-03-17T22:03:02Z" areas="2017-03-17T18:38:02Z"/>

<remark> runtime remark: Test </remark>

</osm>
8 changes: 8 additions & 0 deletions tests/xml/remark-unknown-01.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<osm version="0.6" generator="Overpass API">
<note>The data included in this document is from www.openstreetmap.org. The data is made available under ODbL.</note>
<meta osm_base="2017-03-17T22:03:02Z" areas="2017-03-17T18:38:02Z"/>

<remark> Test remark </remark>

</osm>