Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Error taxonomy

Every ingestion failure the engine records carries a machine-readable kind of the form <group>/<specific>, persisted to the inbound row’s error_kind column — so failures facet by cause family (a prefix match on group) as well as by exact kind. This is what powers the dashboard’s error-queue faceting and triage.

Groups

const ERROR_GROUPS = [
  "parse",
  "structure",
  "field",
  "type",
  "code",
  "unsupported",
  "internal",
] as const;

type ErrorGroup = (typeof ERROR_GROUPS)[number];
groupmeaning
parsepayload-level: not HL7 at all, MSH header missing/broken
structuremessage shape: required segment absent or unusable
fieldsegment present, required field empty
typefield present, value violates its declared HL7 datatype
codecoded value outside its value set / no concept mapping
unsupportedvalid message the engine has no converter for
internalinvariant violations — bugs, not sender data

Raising one

A mapper (or any stage implementation) raises a classified failure with domainError:

import { domainError } from "@health-samurai/interbox";

throw domainError(
  "unsupported",
  "message_type",
  "no converter registered for ORU^R01 with this OBX pattern",
);
// => Error, .name === "InterboxException", .kind === "unsupported/message_type"
function domainError(group: ErrorGroup, kind: string, message: string): Error;

The engine duck-types on .name === "InterboxException" (not instanceof, since the SDK and engine may be bundled from different module graphs) and persists .kind to error_kind. Throwing a plain Error instead still fails the message, but the engine can’t classify it beyond a generic bucket — always prefer domainError for anything a mapper can anticipate.