mirror of
https://github.com/Hestia-Homes/Model.git
synced 2026-07-12 13:29:04 +00:00
Surface both canceljob failure shapes as verbatim rejections 🟩
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
a384b87d8f
commit
157f9fc4b4
1 changed files with 29 additions and 10 deletions
|
|
@ -110,7 +110,7 @@ class AbriClient:
|
|||
if isinstance(outcome, AbriRequestRejected):
|
||||
return outcome
|
||||
|
||||
return self._parse_job_abandoned(outcome)
|
||||
return self._parse_abandon_result(outcome)
|
||||
|
||||
def get_tenant_data(self, place_ref: PlaceRef) -> GetTenantDataResult:
|
||||
outcome = self._exchange(
|
||||
|
|
@ -210,20 +210,39 @@ class AbriClient:
|
|||
)
|
||||
|
||||
@staticmethod
|
||||
def _parse_job_abandoned(root: ET.Element) -> JobAbandoned:
|
||||
def _parse_abandon_result(root: ET.Element) -> AbandonJobResult:
|
||||
# canceljob diverges from the other flows: failure can arrive as a
|
||||
# result document whose cancellation collection is empty and which
|
||||
# carries an ErrorDetails element, rather than the shared failure
|
||||
# envelope. A present JobCancelled is success; a present ErrorDetails
|
||||
# is a business rejection. Neither present is genuinely ambiguous and
|
||||
# must stay retriable — never silently a success or a rejection.
|
||||
job_cancelled = root.find(".//JobCancelled")
|
||||
if job_cancelled is not None:
|
||||
job_no = job_cancelled.get("job_no")
|
||||
if job_no is None:
|
||||
raise AbriResponseParseError("JobCancelled element missing job_no")
|
||||
return JobAbandoned(job_no=job_no)
|
||||
|
||||
if job_cancelled is None:
|
||||
error_details = root.find(".//ErrorDetails")
|
||||
if error_details is not None:
|
||||
return AbriClient._rejection_from_error_details(error_details)
|
||||
|
||||
raise AbriResponseParseError(
|
||||
"canceljob response has neither JobCancelled nor ErrorDetails"
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _rejection_from_error_details(error_details: ET.Element) -> AbriRequestRejected:
|
||||
code = error_details.get("code")
|
||||
message = error_details.get("message")
|
||||
|
||||
if code is None or message is None:
|
||||
raise AbriResponseParseError(
|
||||
"JobCancelled element missing from relay response"
|
||||
"canceljob ErrorDetails missing code or message"
|
||||
)
|
||||
|
||||
job_no = job_cancelled.get("job_no")
|
||||
|
||||
if job_no is None:
|
||||
raise AbriResponseParseError("JobCancelled element missing job_no")
|
||||
|
||||
return JobAbandoned(job_no=job_no)
|
||||
return AbriRequestRejected(code=code, message=message)
|
||||
|
||||
@staticmethod
|
||||
def _parse_tenancy_data(root: ET.Element) -> TenancyData:
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue