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 OK with { "status": "failed" } in the body (e.g. a declined payment).
  • An endpoint that returns 400 / 422 with 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

SDKMinimum versionSupported flow types
Node.js1.8.2Endpoints, 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 the context argument 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 }): void
  • error — 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 context instead 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.