mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-06-19 08:28:10 +02:00
fix: validate workflow status filter to prevent 500 on invalid enum value (#450)
* Validate workflow status filter to prevent 500 on invalid enum value The /workflow/fetch and /workflow/summary endpoints accepted a free-form status query param and passed it straight into a query that casts to the workflow_status PG enum (active/archived). Any other value — e.g. an external caller passing 'published' (a workflow_definitions version state, not a workflow status) — failed deep in Postgres as InvalidTextRepresentationError, surfacing as an unhandled HTTP 500. Add _validate_status_filter() to reject values outside WorkflowStatus with a clean 422 before any DB query, for both the single and comma-separated paths. Add route tests covering invalid, valid-single, comma-separated, and mixed valid/invalid cases. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore: add tests --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
9a1b980f91
commit
d2cda85b78
5 changed files with 186 additions and 26 deletions
|
|
@ -601,16 +601,15 @@ class MPSServiceKeyClient:
|
|||
if response.status_code == 200:
|
||||
return response.json()
|
||||
|
||||
should_retry = (
|
||||
response.status_code == 409
|
||||
and "usage_not_ready" in response.text
|
||||
and attempt < max_attempts
|
||||
usage_not_ready = (
|
||||
response.status_code == 409 and "usage_not_ready" in response.text
|
||||
)
|
||||
if should_retry:
|
||||
if usage_not_ready and attempt < max_attempts:
|
||||
await asyncio.sleep(attempt)
|
||||
continue
|
||||
|
||||
logger.error(
|
||||
log = logger.warning if usage_not_ready else logger.error
|
||||
log(
|
||||
"Failed to report platform usage: "
|
||||
f"{response.status_code} - {response.text}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -39,6 +39,13 @@ async def _organization_uses_mps_billing_v2(organization_id: int) -> bool:
|
|||
return bool(account and account.get("billing_mode") == "v2")
|
||||
|
||||
|
||||
def _is_usage_not_ready_error(exc: Exception) -> bool:
|
||||
response = getattr(exc, "response", None)
|
||||
if getattr(response, "status_code", None) != 409:
|
||||
return False
|
||||
return "usage_not_ready" in (getattr(response, "text", "") or "")
|
||||
|
||||
|
||||
async def report_workflow_run_platform_usage(workflow_run) -> None:
|
||||
"""Report hosted platform usage for a completed workflow run to MPS."""
|
||||
if DEPLOYMENT_MODE == "oss":
|
||||
|
|
@ -91,11 +98,21 @@ async def report_workflow_run_platform_usage(workflow_run) -> None:
|
|||
result,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Failed to report platform usage for workflow run {}: {}",
|
||||
workflow_run.id,
|
||||
e,
|
||||
)
|
||||
if _is_usage_not_ready_error(e):
|
||||
# A run can start and receive an MPS correlation id, then fail or end
|
||||
# before billable STT usage is recorded. MPS returns usage_not_ready
|
||||
# for that no-platform-fee path, so keep it out of error alerts.
|
||||
logger.warning(
|
||||
"Failed to report platform usage for workflow run {}: {}",
|
||||
workflow_run.id,
|
||||
e,
|
||||
)
|
||||
else:
|
||||
logger.error(
|
||||
"Failed to report platform usage for workflow run {}: {}",
|
||||
workflow_run.id,
|
||||
e,
|
||||
)
|
||||
|
||||
|
||||
async def report_completed_workflow_run_platform_usage(workflow_run_id: int) -> None:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue