01
Start with Promise rejection
Catch the rejected load() whether or not the Viewer also has an onError callback. Success and failure 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
Match the channel to the work
Awaitable methods reject their Promise. The callback covers only Viewer-managed work that has no Promise for the application to await; the same failure is never delivered twice.
Awaitable operation
load() and navigation
Parsing, initial rendering, and directly requested navigation reject the Promise returned by that operation.
Catch the operation even when the Viewer also has onError; the callback does not replace Promise rejection.
Background work
onError
Use this for failures from later virtualized page/slide rendering, event-driven work, or embedded-media playback where no application-held Promise exists.
The same failure is never delivered twice. An error already returned by an awaited method is not repeated here.
Document · workbook · presentation
Headless APIs
Loading, rendering and later lazy operations reject the Promise returned by that operation.
PptxPresentation.presentSlide() is the narrow exception: its Promise rejects initial failures, while PresentSlideOptions.onError observes media decode or playback failures after the handle has already been returned.
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 only for background failures that have no Promise to await.
const canvas = document.querySelector<HTMLCanvasElement>('#preview') as HTMLCanvasElement;
const viewer = new DocxViewer(canvas, {
onError(error) {
showPreviewError(previewErrorMessage(error));
reportError(error); // Keep this callback non-throwing.
},
});
try {
// Awaitable methods reject regardless of whether onError is present.
await viewer.load(await file.arrayBuffer());
showPreview();
} catch (error) {
showPreviewError(previewErrorMessage(error));
reportError(error);
}
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
- Catch every Viewer method that returns a Promise, including
load(). - Use
onError only when the application must observe background Viewer work. - 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.