01
Start with Promise rejection
For a basic file preview, omit onError and catch the rejected load(). Success and failure then follow normal Promise semantics.
import { DocxViewer } from '@silurus/ooxml/docx';
// Start here when you only need to know whether the initial load succeeded.
const canvas = document.querySelector<HTMLCanvasElement>('#preview') as HTMLCanvasElement;
const viewer = new DocxViewer(canvas);
const source = await file.arrayBuffer();
try {
await viewer.load(source);
showPreview();
} catch (error) {
showPreviewError('This file could not be previewed.');
reportError(error); // Keep the original error for diagnostics.
}
Use documented fields.Branch on an exported error class or error.code, never the message text.
Show a product-level message.Do not expose ZIP part names, byte counters or parser diagnostics directly to end users.
Keep a fallback.Some network, rendering, browser and media failures intentionally remain ordinary JavaScript errors.
02
Choose the delivery model
The Viewer changes its initial-load behavior when onError is supplied. Choose deliberately rather than combining both models.
Simplest · recommended to start
Viewer without onError
Initial load and parse failures reject load(), so one try/catch determines whether the preview opened.
Later Viewer-managed render or media failures cannot reject an already-settled load Promise and are written to console.error.
Long-lived Viewer
Viewer with onError
Use this when your application must receive failures from later page, slide, sheet, image or media work as well as the initial load.
A failed initial load calls the callback and load() resolves. Update application state in the callback; resolution alone is not proof that rendering succeeded.
Document · workbook · presentation
Headless APIs
Headless methods have no error callback. Loading and later lazy operations reject the Promise returned by that operation.
Catch each operation that can read a new package part or decode a new resource.
Keep onError non-throwing. Record the original error and update UI state inside the callback; throwing from the callback replaces or creates another application error.
03
Decide what the user should see
Handle the narrow, actionable cases first and finish with one generic fallback.
| Check | What it means | Recommended application response |
OoxmlError | The container is encrypted, legacy or not OOXML. | Ask for a password, request conversion, or reject the file according to error.code. |
OoxmlResourceLimitError | A measured package or format resource crossed a limit. | Show “too large or complex to preview.” Only suggest changing configuration when configurable is true. |
OoxmlDecodedImageLimitError | An embedded raster image crossed a non-configurable decode safety ceiling. | Explain that the document contains an image that is too large to preview. |
code === 'parser-crashed' | The WebAssembly parser trapped; the exact underlying cause is unavailable. | Show a generic processing failure, retain diagnostics, and do not label it as OOM. |
| Fallback | A network, browser, configuration, rendering, worker or media failure without a stable typed code. | Show a generic failure and report the original error. Do not parse its message. |
04
Use one translation function
Keep library diagnostics separate from the short, stable messages your product shows to its users.
import {
DocxViewer,
OoxmlDecodedImageLimitError,
OoxmlError,
OoxmlResourceLimitError,
} from '@silurus/ooxml/docx';
export function previewErrorMessage(error: unknown): string {
if (error instanceof OoxmlError) {
switch (error.code) {
case 'encrypted': return 'Enter the password to preview this file.';
case 'invalid-password': return 'The password is incorrect.';
case 'unsupported-encryption': return 'This encryption method is not supported.';
case 'legacy-binary-format': return 'Convert this file to .docx, .xlsx or .pptx first.';
case 'not-ooxml': return 'This is not a supported Office Open XML file.';
}
}
if (error instanceof OoxmlResourceLimitError) {
return error.details.violation.configurable
? 'This file is larger or more complex than this app allows.'
: 'This file exceeds a safety limit and cannot be previewed.';
}
if (error instanceof OoxmlDecodedImageLimitError) {
return 'This file contains an image that is too large to preview.';
}
return 'This file could not be previewed.';
}
// Add onError when the Viewer must also report failures that happen after load.
const canvas = document.querySelector<HTMLCanvasElement>('#preview') as HTMLCanvasElement;
let initialLoadFailed = false;
const viewer = new DocxViewer(canvas, {
onError(error) {
initialLoadFailed = true;
showPreviewError(previewErrorMessage(error));
reportError(error); // Keep this callback non-throwing.
},
});
// A load failure is delivered above, so this Promise resolves when onError exists.
initialLoadFailed = false;
await viewer.load(await file.arrayBuffer());
if (!initialLoadFailed) showPreview();
The same error classes are re-exported from the DOCX, XLSX and PPTX entry points. Replace the Viewer and constructor target for the selected format.
Container failure
OoxmlError
This is the actionable container-level error. Use error.code; the human-readable message is diagnostic text and may change.
encryptedNo password was supplied.Ask for a password and retry.
invalid-passwordThe supplied password did not decrypt the file.Ask the user to check it and retry.
unsupported-encryptionThe file uses an encryption scheme the library cannot decrypt.Request an unencrypted or supported copy.
legacy-binary-formatThe input is .doc, .xls or .ppt, not OOXML.Request conversion to the corresponding modern format.
not-ooxmlThe bytes are not a recognized OOXML package.Reject the file as unsupported or invalid.
Resource governance
OoxmlResourceLimitError
error.code is ooxml-resource-limit. The operation was stopped when a measured value crossed a configured policy or implementation hard ceiling. Read error.details instead of parsing the message.
error.details and error.details.violation
details.stageWhere the failure occurred: container, decompression, parsing, serialization, layout, rendering or worker.
formatdocx, xlsx or pptx.
operationThe library operation that was stopped.
resourceThe measured resource family, such as an archive entry, XML tree or worksheet row.
metricHow the resource was measured: bytes, count, depth or another documented axis.
limitThe ceiling for this metric.
observedThe value seen when the operation was rejected; it is not necessarily a complete-file total.
configurabletrue means a public resource setting can change it. false means the hard ceiling cannot be disabled.
usageA content-free archive usage snapshot captured at failure time.
part?An optional package-part identifier when one is available.
details.violation.usage
archiveEntryCount, declaredInflatedBytes, optional largestInflatedEntryBytes, distinctInflatedBytes and operationInflatedBytes describe the work observed up to the failure.
If configurable is trueReview the measured metric and your application’s expected files before raising the corresponding resourceLimits value. Do not retry automatically with no limit.
If configurable is falseThe current library version will not process this resource. Ask for a smaller or simplified file instead of suggesting a configuration change.
The compressed upload size cannot predict the inflated size. Limits are enforced while package parts are inspected and decompressed. These counters reduce predictable memory risk, but do not measure or guarantee peak JavaScript, Canvas, image-decoder or WebAssembly memory. Worker mode can improve failure containment, but it is not a separate process or strict memory sandbox.
Raster image safety
OoxmlDecodedImageLimitError
error.code is ooxml-decoded-image-limit. Inspect metric, limit and observed. The metric is image-pixels or active-decoded-bytes.
This limit is not configurable. It prevents dangerous decoded surfaces before or during image work. A browser or device may still impose a lower image or Canvas limit, so ordinary decode failures can occur below this ceiling.
WebAssembly trap
parser-crashed
This code means the library recognized a WebAssembly trap and discarded the affected parser instance. It does not mean “out of memory.”
At the current WebAssembly boundary, Rust panic, allocation failure, stack overflow and explicit unreachable can all reach JavaScript as the same WebAssembly.RuntimeError. The runtime exposes the trap only after the original Rust cause has been erased, so the library cannot reliably reconstruct which event occurred.
Show a generic “could not process this file” result. Preserve the original error for diagnostics, do not repeatedly retry the same file automatically, and do not report the failure as OOM without independent evidence from the host environment.
Fallback
Untyped errors
Configuration, fetch, parser, renderer, worker, browser and media failures may remain ordinary Error, TypeError or RangeError values. This is intentional where the library cannot promise a stable cause classification.
Messages are for logs and diagnostics, not control flow. Keep a generic user-facing fallback and report the original error object to your observability system.
Production checklist
Before shipping
- Choose Promise rejection or
onError intentionally for each Viewer. - Catch every headless operation that can load a package part or decode media.
- Branch only on exported classes and documented
code values. - Translate technical failures into short product-level messages.
- Retain the original error for logs, metrics or reporting.
- Test encrypted, wrong-password, oversized and invalid files in your application.