Skip to content

Commit a3eec22

Browse files
Merge pull request #1384 from VWS-Python/conn-error
Update exception handling to match the latest reality - mostly around how the query endpoint handles matching deleted targets
2 parents 51c001a + eb9bee1 commit a3eec22

File tree

6 files changed

+50
-79
lines changed

6 files changed

+50
-79
lines changed

CHANGELOG.rst

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@ Changelog
66
Next
77
----
88

9-
2020.09.28.0
10-
------------
11-
12-
2020.09.25.0
13-
------------
14-
15-
2020.09.08.0
16-
------------
9+
* Breaking change: The ``vws.exceptions.cloud_reco_exceptions.MatchProcessing`` is now ``vws.exceptions.custom_exceptions.ActiveMatchingTargetsDeleteProcessing``.
10+
* Added new exception ``vws.exceptions.custom_exceptions.RequestEntityTooLarge``.
1711

1812
2020.09.07.0
1913
------------

dev-requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ PyYAML==5.4.1
55
Pygments==2.8.1
66
Sphinx-Substitution-Extensions==2020.9.30.0
77
Sphinx==3.5.3
8-
VWS-Python-Mock==2020.10.3.0
8+
VWS-Python-Mock==2021.3.27.1
99
VWS-Test-Fixtures==2020.9.25.1
1010
autoflake==1.4
1111
check-manifest==0.46

src/vws/exceptions/cloud_reco_exceptions.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@
66
from vws.exceptions.base_exceptions import CloudRecoException
77

88

9-
class MatchProcessing(CloudRecoException):
10-
"""
11-
Exception raised when a query is made with an image which matches a target
12-
which is processing or has recently been deleted.
13-
"""
14-
15-
169
class MaxNumResultsOutOfRange(CloudRecoException):
1710
"""
1811
Exception raised when the ``max_num_results`` given to the Cloud

src/vws/exceptions/custom_exceptions.py

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,6 @@
44
or simple errors given by the cloud recognition service.
55
"""
66

7-
import requests
8-
97

108
class UnknownVWSErrorPossiblyBadName(Exception):
119
"""
@@ -16,14 +14,20 @@ class UnknownVWSErrorPossiblyBadName(Exception):
1614
"""
1715

1816

19-
class ConnectionErrorPossiblyImageTooLarge(requests.ConnectionError):
17+
class RequestEntityTooLarge(Exception):
2018
"""
21-
Exception raised when a ConnectionError is raised from a query. This has
22-
been seen to happen when the given image is too large.
19+
Exception raised when the given image is too large.
2320
"""
2421

2522

2623
class TargetProcessingTimeout(Exception):
2724
"""
2825
Exception raised when waiting for a target to be processed times out.
2926
"""
27+
28+
29+
class ActiveMatchingTargetsDeleteProcessing(Exception):
30+
"""
31+
Exception raised when a query is made with an image which matches a target
32+
which has recently been deleted.
33+
"""

src/vws/query.py

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import datetime
88
import io
9+
from http import HTTPStatus
910
from urllib.parse import urljoin
1011

1112
import requests
@@ -16,12 +17,12 @@
1617
AuthenticationFailure,
1718
BadImage,
1819
InactiveProject,
19-
MatchProcessing,
2020
MaxNumResultsOutOfRange,
2121
RequestTimeTooSkewed,
2222
)
2323
from vws.exceptions.custom_exceptions import (
24-
ConnectionErrorPossiblyImageTooLarge,
24+
ActiveMatchingTargetsDeleteProcessing,
25+
RequestEntityTooLarge,
2526
)
2627
from vws.include_target_data import CloudRecoIncludeTargetData
2728
from vws.reports import QueryResult, TargetData
@@ -77,22 +78,21 @@ def query(
7778
client access key pair is not correct.
7879
~vws.exceptions.cloud_reco_exceptions.MaxNumResultsOutOfRange:
7980
``max_num_results`` is not within the range (1, 50).
80-
~vws.exceptions.cloud_reco_exceptions.MatchProcessing: The given
81-
image matches a target which was recently added, updated or
82-
deleted and Vuforia returns an error in this case.
8381
~vws.exceptions.cloud_reco_exceptions.InactiveProject: The project
8482
is inactive.
85-
~vws.exceptions.custom_exceptions.ConnectionErrorPossiblyImageTooLarge:
86-
The given image is too large.
8783
~vws.exceptions.cloud_reco_exceptions.RequestTimeTooSkewed: There
8884
is an error with the time sent to Vuforia.
8985
~vws.exceptions.cloud_reco_exceptions.BadImage: There is a problem
9086
with the given image. For example, it must be a JPEG or PNG
9187
file in the grayscale or RGB color space.
88+
~vws.exceptions.custom_exceptions.RequestEntityTooLarge: The given
89+
image is too large.
90+
~vws.exceptions.custom_exceptions.ActiveMatchingTargetsDeleteProcessing:
91+
The given image matches a target which was recently deleted.
9292
9393
Returns:
9494
An ordered list of target details of matching targets.
95-
"""
95+
""" # noqa: E501
9696
image_content = image.getvalue()
9797
body = {
9898
'image': ('image.jpeg', image_content, 'image/jpeg'),
@@ -125,24 +125,21 @@ def query(
125125
'Content-Type': content_type_header,
126126
}
127127

128-
try:
129-
response = requests.request(
130-
method=method,
131-
url=urljoin(base=self._base_vwq_url, url=request_path),
132-
headers=headers,
133-
data=content,
134-
)
135-
except requests.exceptions.ConnectionError as exc:
136-
raise ConnectionErrorPossiblyImageTooLarge(
137-
request=exc.request,
138-
response=exc.response,
139-
) from exc
128+
response = requests.request(
129+
method=method,
130+
url=urljoin(base=self._base_vwq_url, url=request_path),
131+
headers=headers,
132+
data=content,
133+
)
134+
135+
if response.status_code == HTTPStatus.REQUEST_ENTITY_TOO_LARGE:
136+
raise RequestEntityTooLarge
140137

141138
if 'Integer out of range' in response.text:
142139
raise MaxNumResultsOutOfRange(response=response)
143140

144141
if 'No content to map due to end-of-input' in response.text:
145-
raise MatchProcessing(response=response)
142+
raise ActiveMatchingTargetsDeleteProcessing
146143

147144
result_code = response.json()['result_code']
148145
if result_code != 'Success':

tests/test_cloud_reco_exceptions.py

Lines changed: 20 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
"""
44

55
import io
6+
import time
67
from http import HTTPStatus
78

89
import pytest
9-
import requests
1010
from mock_vws import MockVWS
1111
from mock_vws.database import VuforiaDatabase
1212
from mock_vws.states import States
@@ -15,12 +15,14 @@
1515
from vws.exceptions.base_exceptions import CloudRecoException
1616
from vws.exceptions.cloud_reco_exceptions import (
1717
AuthenticationFailure,
18+
BadImage,
1819
InactiveProject,
19-
MatchProcessing,
2020
MaxNumResultsOutOfRange,
21+
RequestTimeTooSkewed,
2122
)
2223
from vws.exceptions.custom_exceptions import (
23-
ConnectionErrorPossiblyImageTooLarge,
24+
ActiveMatchingTargetsDeleteProcessing,
25+
RequestEntityTooLarge,
2426
)
2527

2628

@@ -50,68 +52,49 @@ def test_image_too_large(
5052
png_too_large: io.BytesIO,
5153
) -> None:
5254
"""
53-
A ``ConnectionErrorPossiblyImageTooLarge`` exception is raised if an
54-
image which is too large is given.
55+
A ``RequestEntityTooLarge`` exception is raised if an image which is too
56+
large is given.
5557
"""
56-
with pytest.raises(ConnectionErrorPossiblyImageTooLarge) as exc:
58+
with pytest.raises(RequestEntityTooLarge):
5759
cloud_reco_client.query(image=png_too_large)
5860

59-
assert isinstance(exc.value, requests.ConnectionError)
60-
6161

6262
def test_cloudrecoexception_inheritance() -> None:
6363
"""
6464
CloudRecoService-specific exceptions inherit from CloudRecoException.
6565
"""
6666
subclasses = [
67-
MatchProcessing,
6867
MaxNumResultsOutOfRange,
68+
InactiveProject,
69+
BadImage,
70+
AuthenticationFailure,
71+
RequestTimeTooSkewed,
6972
]
7073
for subclass in subclasses:
7174
assert issubclass(subclass, CloudRecoException)
7275

7376

74-
def test_base_exception(
75-
vws_client: VWS,
76-
cloud_reco_client: CloudRecoService,
77-
high_quality_image: io.BytesIO,
78-
) -> None:
79-
"""
80-
``CloudRecoException``s has a response property.
81-
"""
82-
vws_client.add_target(
83-
name='x',
84-
width=1,
85-
image=high_quality_image,
86-
active_flag=True,
87-
application_metadata=None,
88-
)
89-
90-
with pytest.raises(CloudRecoException) as exc:
91-
cloud_reco_client.query(image=high_quality_image)
92-
93-
assert exc.value.response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
94-
95-
96-
def test_match_processing(
77+
def test_active_matching_targets_delete_processing(
9778
vws_client: VWS,
9879
cloud_reco_client: CloudRecoService,
9980
high_quality_image: io.BytesIO,
10081
) -> None:
10182
"""
102-
A ``MatchProcessing`` exception is raised when a target in processing is
103-
matched.
83+
A ``ActiveMatchingTargetsDeleteProcessing`` exception is raised when a
84+
target which has recently been deleted is matched.
10485
"""
105-
vws_client.add_target(
86+
target_id = vws_client.add_target(
10687
name='x',
10788
width=1,
10889
image=high_quality_image,
10990
active_flag=True,
11091
application_metadata=None,
11192
)
112-
with pytest.raises(MatchProcessing) as exc:
93+
vws_client.wait_for_target_processed(target_id=target_id)
94+
vws_client.delete_target(target_id=target_id)
95+
time.sleep(0.2)
96+
with pytest.raises(ActiveMatchingTargetsDeleteProcessing):
11397
cloud_reco_client.query(image=high_quality_image)
114-
assert exc.value.response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
11598

11699

117100
def test_authentication_failure(high_quality_image: io.BytesIO) -> None:

0 commit comments

Comments
 (0)