Skip to content

Commit

Permalink
Fix duplicated name error msg (#295)
Browse files Browse the repository at this point in the history
* Catching and identifying the situations where a duplicate Name is the issue in a save

* introduce an inherent Error for duplicated names

* upgrading reliability and no reference to namespaces anymore.
  • Loading branch information
InnocentBug authored Aug 29, 2023
1 parent 01a8053 commit 58b44c2
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
14 changes: 13 additions & 1 deletion src/cript/api/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
CRIPTAPIRequiredError,
CRIPTAPISaveError,
CRIPTConnectionError,
CRIPTDuplicateNameError,
InvalidHostError,
InvalidVocabulary,
)
Expand Down Expand Up @@ -683,7 +684,18 @@ def _internal_save(self, node, save_values: Optional[_InternalSaveValues] = None
# If we get an error we may be able to fix, we to handle this extra and save the bad node first.
# Errors with this code, may be fixable
if response["code"] in (400, 409):
returned_save_values = _fix_node_save(self, node, response, save_values)
try:
returned_save_values = _fix_node_save(self, node, response, save_values)
except CRIPTAPISaveError as exc:
# If the previous error was a duplicated name issue
if "duplicate item [{'name':" in str(response["error"]):
# And (second condition) the request failed bc of the now suppressed name
if "'name' is a required property" in exc.api_response:
# Raise a save error, with the nice name related error message
raise CRIPTDuplicateNameError(response, json_data, exc) from exc
# Else just raise the exception as normal.
raise exc

save_values += returned_save_values

# Handle errors from patching with too many attributes
Expand Down
34 changes: 32 additions & 2 deletions src/cript/api/exceptions.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from typing import List, Optional, Set
import json
from typing import List, Set

from cript.exceptions import CRIPTException

Expand Down Expand Up @@ -110,7 +111,7 @@ class CRIPTAPISaveError(CRIPTException):
http_code: str
api_response: str

def __init__(self, api_host_domain: str, http_code: str, api_response: str, patch_request: bool, pre_saved_nodes: Optional[Set[str]] = None, json_data: Optional[str] = None):
def __init__(self, api_host_domain: str, http_code: str, api_response: str, patch_request: bool, pre_saved_nodes: Set[str], json_data: str):
self.api_host_domain = api_host_domain
self.http_code = http_code
self.api_response = api_response
Expand All @@ -129,6 +130,35 @@ def __str__(self) -> str:
return error_message


class CRIPTDuplicateNameError(CRIPTAPISaveError):
def __init__(self, api_response, json_data: str, parent_cript_save_error: CRIPTAPISaveError):
super().__init__(
parent_cript_save_error.api_host_domain, api_response["code"], api_response=api_response["error"], patch_request=parent_cript_save_error.patch_request, pre_saved_nodes=parent_cript_save_error.pre_saved_nodes, json_data=json_data
)

# We don't care if the data is invalid JSON
# So let's catch a couple of common exceptions and ensure still meaning error messages
# (and debug info in case it does happen.)
try:
json_dict = json.loads(self.json_data)
except (TypeError, json.JSONDecodeError):
self.name = "unknown_name"
self.node = "UnknownType"
try:
self.name = json_dict["name"]
except KeyError:
self.name = "unknown_name_key"
try:
self.node = json_dict["node"][0]
except KeyError:
self.node = "UnknownTypeKey"
except IndexError:
self.node = "UnknownTypeIdx"

def __str__(self) -> str:
return f"The name '{self.name}' for your {self.node} node is already present in CRIPT. Either choose a new name!" # , or consider namespaces like 'MyNameSpace::{self.name}' instead."


class InvalidHostError(CRIPTException):
"""
## Definition
Expand Down

0 comments on commit 58b44c2

Please sign in to comment.