Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

377 fix error handling in context broker client #382

Merged
merged 5 commits into from
Jan 31, 2025
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
4 changes: 2 additions & 2 deletions filip/clients/ngsi_ld/cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ def post_entity(
return res.headers.get("Location")
res.raise_for_status()
except requests.RequestException as err:
if err.response.status_code == 409:
if err.response is not None and err.response.status_code == 409:
if append: # 409 entity already exists
return self.append_entity_attributes(entity=entity)
elif update:
Expand Down Expand Up @@ -454,7 +454,7 @@ def replace_existing_attributes_of_entity(
else:
res.raise_for_status()
except requests.RequestException as err:
if append and err.response.status_code == 207:
if err.response is not None and append and err.response.status_code == 207:
return self.append_entity_attributes(entity=entity)
msg = f"Could not replace attribute of entity {entity.id} !"
self.log_error(err=err, msg=msg)
Expand Down
54 changes: 38 additions & 16 deletions filip/clients/ngsi_v2/cb.py
Original file line number Diff line number Diff line change
Expand Up @@ -261,15 +261,16 @@ def post_entity(
return res.headers.get("Location")
res.raise_for_status()
except requests.RequestException as err:
if update and err.response.status_code == 422:
return self.override_entity(entity=entity, key_values=key_values)
if patch and err.response.status_code == 422:
if not key_values:
return self.patch_entity(
entity=entity, override_attr_metadata=override_attr_metadata
)
else:
return self._patch_entity_key_values(entity=entity)
if err.response is not None:
if update and err.response.status_code == 422:
return self.override_entity(entity=entity, key_values=key_values)
if patch and err.response.status_code == 422:
if not key_values:
return self.patch_entity(
entity=entity, override_attr_metadata=override_attr_metadata
)
else:
return self._patch_entity_key_values(entity=entity)
msg = f"Could not post entity {entity.id}"
self.log_error(err=err, msg=msg)
raise
Expand Down Expand Up @@ -1980,6 +1981,7 @@ def does_entity_exist(self, entity_id: str, entity_type: str) -> bool:
res.raise_for_status()
except requests.RequestException as err:
if err.response is None or not err.response.status_code == 404:
self.log_error(err=err, msg="Checking entity existence failed!")
raise
return False

Expand Down Expand Up @@ -2076,9 +2078,20 @@ def patch_entity(
attr_name=old_attr.name,
)
except requests.RequestException as err:
# if the attribute is provided by a registration the
# deletion will fail
if not err.response.status_code == 404:
msg = (
f"Failed to delete attribute {old_attr.name} of "
f"entity {new_entity.id}."
)
if err.response is not None and err.response.status_code == 404:
# if the attribute is provided by a registration the
# deletion will fail
msg += (
f" The attribute is probably provided "
f"by a registration."
)
self.log_error(err=err, msg=msg)
else:
self.log_error(err=err, msg=msg)
raise
else:
# Check if attributed changed in any way, if yes update
Expand All @@ -2092,10 +2105,19 @@ def patch_entity(
override_metadata=override_attr_metadata,
)
except requests.RequestException as err:
# if the attribute is provided by a registration the
# update will fail
if not err.response.status_code == 404:
raise
msg = (
f"Failed to update attribute {old_attr.name} of "
f"entity {new_entity.id}."
)
if err.response is not None and err.response.status_code == 404:
# if the attribute is provided by a registration the
# update will fail
msg += (
f" The attribute is probably provided "
f"by a registration."
)
self.log_error(err=err, msg=msg)
raise

# Create new attributes
update_entity = ContextEntity(id=entity.id, type=entity.type)
Expand Down
6 changes: 5 additions & 1 deletion filip/clients/ngsi_v2/iota.py
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,11 @@ def does_device_exists(self, device_id: str) -> bool:
self.get_device(device_id=device_id)
return True
except requests.RequestException as err:
if not err.response.status_code == 404:
if err.response is None or not err.response.status_code == 404:
self.log_error(
err=err,
msg=f"Error while checking existence for device {device_id}",
)
raise
return False

Expand Down
27 changes: 25 additions & 2 deletions tests/clients/test_ngsi_v2_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
from pathlib import Path

from filip.models.base import FiwareHeader
from filip.clients.ngsi_v2.client import HttpClient

from filip.clients.ngsi_v2.client import HttpClient, HttpClientConfig
from filip.models.ngsi_v2 import ContextEntity
from tests.config import settings, generate_servicepath


Expand Down Expand Up @@ -205,6 +205,29 @@ def test_session_handling(self):
self._test_connections(client=client)
self._test_change_of_headers(client=client)

def test_handling_ssl_error(self):
"""
Test if the client can handle SSL errors correctly

Returns:
None
"""
url_with_ssl_error = "https://self-signed.badssl.com/"
config = HttpClientConfig(
cb_url=url_with_ssl_error,
iota_url=url_with_ssl_error,
ql_url=url_with_ssl_error,
)
client = HttpClient(config=config, fiware_header=self.fh)
with self.assertRaises(requests.exceptions.SSLError):
client.cb.post_entity(entity=ContextEntity(id="test", type="test"))
with self.assertRaises(requests.exceptions.SSLError):
client.cb.patch_entity(entity=ContextEntity(id="test", type="test"))
with self.assertRaises(requests.exceptions.SSLError):
client.iota.does_device_exists(device_id="test")
with self.assertRaises(requests.exceptions.SSLError):
client.timeseries.get_version()

def tearDown(self) -> None:
"""
Clean up artifacts
Expand Down