Skip to content

Diagnosing what was degraded (onDegradation) ​

Conventions used by the examples on this page

So the same preamble is not repeated everywhere, the examples below assume this setting. Each block then shows only what it is demonstrating.

ts
import { loadReqIfPackage, ReqIfIndex } from "reqif-preview";

// The bytes of your .reqif or .reqifz file.
// See [Getting started](/guide/getting-started) for reading them from an
// <input type="file">, from Node, or from a URL.
declare const bytes: Uint8Array;

const pkg = await loadReqIfPackage(bytes);
const doc = pkg.document; // the first document in the package

// pkg.documents, not pkg.document: this is what resolves relations that cross
// the boundary between two .reqif files inside one .reqifz.
const index = new ReqIfIndex(pkg.documents);

const spec = doc.coreContent.specifications[0];
const obj = index.specObjects.get(spec.children[0].objectRef)!;

Past the parsing stage, nothing throws. A surprising input degrades locally and the rest of the document still renders. That is the right behaviour in production — a requirements preview beats a blank page — and a miserable one in support: faced with "things are missing from my preview", there is nothing to inspect.

ts
import type { DegradationEvent } from "reqif-preview";

const events: DegradationEvent[] = [];
const html = await renderPackageToHtml(pkg, { onDegradation: (e) => events.push(e) });

// [{ code: "attachment-missing", message: 'No attachment resolved for "schema.png".',
//    detail: { path: "schema.png" } }, …]

The rendering is strictly identical with or without a handler

The option changes nothing about the output. It only makes visible decisions that were already being taken, silently. You can therefore wire it up in production without fearing a change in behaviour.

The codes emitted ​

CodeSituation
attachment-missinga referenced attachment no resolver can find
attachment-too-largean attachment over maxInlineBytes, left unresolved
unresolved-referencea SpecRelation pointing at an object absent from the render
duplicate-dom-idan object rendered more than once; only the first carries the id
orphan-attribute-valuea value whose AttributeDefinition is absent from the declared SpecType
missing-spec-objecta tree node pointing at a SpecObject that does not exist
custom-renderer-threwa customAttributeRenderers threw and was ignored
custom-renderer-unbalanced-htmlcustom HTML left unbalanced, escaped as text
custom-renderer-raw-stringa renderer returned a bare string; escaped as text
custom-renderer-dropped-attra custom-renderer node carried a non-allow-listed attribute
dropped-taga tag removed along with its subtree (<script>, <iframe>…)
unwrapped-taga non-allow-listed tag unwrapped, children kept
dropped-style-declarationan invalid style declaration discarded
dropped-hrefa javascript: / vbscript: / data: href neutralised
unparsable-datea date that could not be parsed, shown as-is
invalid-localeIntl rejected the configured locale

A diagnostic channel, not a log ​

WARNING

dropped-tag and unwrapped-tag can fire thousands of times on a large export: every disallowed Word formatting <span> counts. Filter by code, or only turn the option on while investigating.

In practice what you can act on is the aggregate, not the raw list:

ts
const byCode = new Map<string, number>();
await renderPackageToHtml(pkg, {
  onDegradation: (e) => byCode.set(e.code, (byCode.get(e.code) ?? 0) + 1),
});
console.table([...byCode]);

That is exactly what the "Diagnostics" panel of the playground does: one row per code, with a counter and a sample message.

A handler that throws is ignored ​

An exception in your handler is caught and swallowed. A diagnostic channel that broke what it was observing would be worse than no channel at all.

What to look at first ​

Reported symptomCode to look for
"The images do not show"attachment-missing, attachment-too-large
"This traceability link goes nowhere"unresolved-reference
"Clicking a link takes me to the wrong place"duplicate-dom-id
"A whole requirement is missing"missing-spec-object
"An attribute is absent from the technical panel"orphan-attribute-value
"My formatting is lost"dropped-tag, unwrapped-tag, dropped-style-declaration
"My custom badge shows as plain text"custom-renderer-unbalanced-html
"The dates look odd"unparsable-date, invalid-locale

Released under the MIT licence. Conformant to OMG ReqIF v1.2 (formal/2016-07-01).