Mark a Flow as Failed
Manually flag an HTTP or queue flow as failed when no exception was raised or auto-detected.
Overview
Use hud_sdk.set_failure() to explicitly mark the current execution (flow) as failed even when no exception occurred and Hud did not auto-detect a problem.
Marking these failures is what lets Hud treat them like any auto-detected failure. Use it so that:
- Your error rate is accurate — the failed flow is counted, so error-rate metrics reflect reality instead of hiding gracefully-handled failures.
- Alerts fire — Endpoint Error and Post-Deploy Error rules pick up the failure and can alert on it.
- Forensics are collected — Hud captures forensics for the failed execution so you can debug it later.
This is useful for business-rule failures, invalid input you handle gracefully, soft-denies, or any condition you consider a failure.
When to Use
Hud automatically detects failures from unhandled exceptions and 5xx responses. But many services handle errors gracefully and never surface them as an exception or a 5xx, so Hud has no way to know the flow failed. For example:
- An endpoint that returns
200 OKwith{"status": "failed"}in the body (e.g. a declined payment). - An endpoint that returns
400/422with a validation error instead of raising. - A queue consumer that swallows a bad message and logs it instead of raising.
- Any business-rule or policy failure — missing input, soft-deny, or a disabled feature.
In these cases, call set_failure() so the failure is recorded and surfaced in Hud.
Requirements
| SDK | Minimum version | Supported flow types |
|---|---|---|
| Python | 0.4.2 | Endpoints, Queues |
Important Notes
set_failure()must be called during the active handling of a request or message (an active flow). Calling it outside a flow has no effect.- The failure message must be low-cardinality — a short, constant, stable string (e.g.
"Payment provider timeout"). Hud groups occurrences into a single issue by this exact string, so never put variable or high-cardinality data (user IDs, order IDs, timestamps, request IDs) in it — pass that in the keyword metadata instead. High-cardinality messages fragment your issues and distort the error rate.- One call per flow — if you call it multiple times in the same flow, the last call is the one recorded.
Example #1: HTTP Handler
from flask import Flask, request
import hud_sdk
app = Flask(__name__)
@app.route("/checkout", methods=["POST"])
def checkout():
items = request.json.get("items")
if not items:
hud_sdk.set_failure("Checkout attempted with no items")
return {"status": "failure", "reason": "no items in cart"}, 400
payment_result = process_payment(request.json)
if not payment_result["success"]:
hud_sdk.set_failure(
"Payment failed",
reason=payment_result["reason"],
provider=payment_result["provider"],
)
# Note: returns 200 — the server handled it, but Hud counts it as a failure
return {"status": "payment_failed", "reason": payment_result["reason"]}
return {"status": "ok"}Example #2: Queue Consumer
import hud_sdk
def process_message(msg):
if msg.get("type") not in ["create", "update"]:
hud_sdk.set_failure("Unsupported message type", message_type=msg.get("type"))
return
# Normal handling logic here
...API Reference
hud_sdk.set_failure(error: str, **metadata: str | int | float | bool) -> Noneerror— a short, stable string describing the failure. Used to group failures into issues.**metadata(optional) — key-value metadata passed as keyword arguments, attached to the failure for debugging (e.g.reason="timeout"). Values can be strings, numbers, or booleans.
Best Practices
- Keep failure messages low-cardinality. Use a small, fixed set of constant strings.
"Payment provider timeout"groups well;"Payment failed for user 12345 at 2026-05-20T10:30:00"is high-cardinality and creates a new issue for every occurrence, which breaks grouping and error-rate accuracy. - Use metadata for variable data. Put user IDs, request IDs, and other variable values in the keyword metadata instead of the error string.
- One call per flow. If you call
set_failure()multiple times in the same flow, the last call is recorded.
Notes
- Works with any HTTP status. The flow is marked as failed regardless of the response status code. If the flow also returns 5xx, it is counted once (not double-counted).
- No rule configuration needed. Existing Endpoint Error and Post-Deploy Error rules automatically detect user-defined failures.
set_failure also works alongside set_context and manual flows.
Updated about 1 month ago

