Mark a Flow as Failed
Manually flag an HTTP or queue flow as failed when no exception was raised or auto-detected.
Overview
Use setFailure() to explicitly mark the current execution (flow) as failed even when no exception was thrown 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.
setFailure is exported from hud-sdk/api.
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 throwing. - 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 setFailure() so the failure is recorded and surfaced in Hud.
Requirements
| SDK | Minimum version | Supported flow types |
|---|---|---|
| Node.js | 1.8.2 | Endpoints, Queues |
Important Notes
setFailure()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 thecontextargument 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 Endpoint
const hud = require("hud-sdk/api");
const express = require("express");
const app = express();
app.post("/checkout", (req, res) => {
const { items, paymentMethod } = req.body;
if (!items || items.length === 0) {
hud.setFailure("Checkout attempted with no items");
return res.status(400).json({ error: "No items in cart" });
}
const paymentResult = processPayment(paymentMethod, items);
if (!paymentResult.success) {
hud.setFailure("Payment failed", {
reason: paymentResult.reason,
provider: paymentResult.provider,
});
// Note: returns 200 — the server handled it, but Hud counts it as a failure
return res.status(200).json({
status: "payment_failed",
reason: paymentResult.reason,
});
}
res.json({ status: "ok", orderId: paymentResult.orderId });
});import { setFailure } from "hud-sdk/api";
import express from "express";
const app = express();
app.post("/checkout", (req, res) => {
const { items, paymentMethod } = req.body;
if (!items || items.length === 0) {
setFailure("Checkout attempted with no items");
return res.status(400).json({ error: "No items in cart" });
}
// ...continue with normal flow
});Example #2: Queue Consumer
const { setFailure } = require("hud-sdk/api");
async function processMessage(msg) {
if (!["create", "update"].includes(msg.type)) {
setFailure("Unsupported message type", { messageType: msg.type });
return;
}
// Normal handling logic here
}API Reference
setFailure(error: string, context?: { [key: string]: string | number | boolean }): voiderror— a short, stable string describing the failure. Used to group failures into issues.context(optional) — key-value metadata attached to the failure for debugging (e.g.reason,provider). 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 context for variable data. Put user IDs, request IDs, and other variable values in
contextinstead of the error string. - One call per flow. If you call
setFailure()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.
setFailure also works alongside setContext and manual flows.

