Skip to content

Commit e5ad0ff

Browse files
committed
PR Feedback 1
1 parent bb8243e commit e5ad0ff

File tree

3 files changed

+70
-7
lines changed

3 files changed

+70
-7
lines changed

durabletask/entities/entity_instance_id.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
class EntityInstanceId:
22
def __init__(self, entity: str, key: str):
3-
if not entity or not key:
4-
raise ValueError("Entity name and key cannot be empty.")
5-
if "@" in key:
6-
raise ValueError("Entity key cannot contain '@' symbol.")
3+
EntityInstanceId.validate_entity_name(entity)
4+
EntityInstanceId.validate_key(key)
75
self.entity = entity.lower()
86
self.key = key
97

@@ -46,3 +44,41 @@ def parse(entity_id: str) -> "EntityInstanceId":
4644
except ValueError as ex:
4745
raise ValueError(f"Invalid entity ID format: {entity_id}") from ex
4846
return EntityInstanceId(entity=entity, key=key)
47+
48+
@staticmethod
49+
def validate_entity_name(name: str) -> None:
50+
"""Validate that the entity name does not contain invalid characters.
51+
52+
Parameters
53+
----------
54+
name : str
55+
The entity name to validate.
56+
57+
Raises
58+
------
59+
ValueError
60+
If the name is not a valid entity name.
61+
"""
62+
if not name:
63+
raise ValueError("Entity name cannot be empty.")
64+
if "@" in name:
65+
raise ValueError("Entity name cannot contain '@' symbol.")
66+
67+
@staticmethod
68+
def validate_key(key: str) -> None:
69+
"""Validate that the entity key does not contain invalid characters.
70+
71+
Parameters
72+
----------
73+
key : str
74+
The entity key to validate.
75+
76+
Raises
77+
------
78+
ValueError
79+
If the key is not a valid entity key.
80+
"""
81+
if not key:
82+
raise ValueError("Entity key cannot be empty.")
83+
if "@" in key:
84+
raise ValueError("Entity key cannot contain '@' symbol.")

durabletask/worker.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,8 @@ def add_entity(self, fn: task.Entity, name: Optional[str] = None) -> str:
199199
return name
200200

201201
def add_named_entity(self, name: str, fn: task.Entity) -> None:
202-
if not name:
203-
raise ValueError("A non-empty entity name is required.")
204202
name = name.lower()
203+
EntityInstanceId.validate_entity_name(name)
205204
if name in self.entities:
206205
raise ValueError(f"A '{name}' entity already exists.")
207206

@@ -906,7 +905,10 @@ def set_complete(
906905
try:
907906
result_json = result if is_result_encoded else shared.to_json(result)
908907
except (ValueError, TypeError):
909-
result_json = shared.to_json(str(JsonEncodeOutputException(result)))
908+
self._is_complete = False
909+
self._result = None
910+
self.set_failed(JsonEncodeOutputException(result))
911+
return
910912
action = ph.new_complete_orchestration_action(
911913
self.next_sequence_number(), status, result_json
912914
)

tests/durabletask-azuremanaged/test_dts_orchestration_e2e.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,3 +569,28 @@ def empty_orchestrator(ctx: task.OrchestrationContext, _):
569569
assert uuid.UUID(results[0]) != uuid.UUID(results[1])
570570
assert uuid.UUID(results[0]) != uuid.UUID(results[2])
571571
assert uuid.UUID(results[1]) != uuid.UUID(results[2])
572+
573+
574+
def test_orchestration_with_unparsable_output_fails():
575+
def test_orchestrator(ctx: task.OrchestrationContext, _):
576+
return Exception("This is not JSON serializable")
577+
578+
# Start a worker, which will connect to the sidecar in a background thread
579+
with DurableTaskSchedulerWorker(host_address=endpoint, secure_channel=True,
580+
taskhub=taskhub_name, token_credential=None) as w:
581+
w.add_orchestrator(test_orchestrator)
582+
w.start()
583+
584+
c = DurableTaskSchedulerClient(host_address=endpoint, secure_channel=True,
585+
taskhub=taskhub_name, token_credential=None)
586+
id = c.schedule_new_orchestration(test_orchestrator)
587+
state = c.wait_for_orchestration_completion(id, timeout=30)
588+
589+
assert state is not None
590+
assert state.name == task.get_name(test_orchestrator)
591+
assert state.instance_id == id
592+
assert state.failure_details is not None
593+
assert state.failure_details.error_type == "JsonEncodeOutputException"
594+
assert state.failure_details.message.startswith("The orchestration result could not be encoded. Object details:")
595+
assert state.failure_details.message.find("This is not JSON serializable") != -1
596+
assert state.runtime_status == client.OrchestrationStatus.FAILED

0 commit comments

Comments
 (0)