How Batch Mode in OfficeCLI Handles Multiple Operations and Error Handling
OfficeCLI forwards an array of commands as a single JSON payload to the resident process, executing them in one round-trip while isolating or aborting on failures based on the stopOnError configuration.
OfficeCLI’s Node SDK implements batch mode as a high-throughput mechanism for applying multiple spreadsheet transformations without spawning separate processes per command. By serializing operations into a structured envelope and routing them through a persistent pipe, the library minimizes latency and provides deterministic error handling policies. Understanding how the batch() method in sdk/node/index.js constructs payloads and manages transport resilience is critical for production automation workflows.
How the Batch Payload Is Constructed
The batch(items, options) method aggregates commands into a JSON object with three fields: batchJson, force, and stopOnError. The batchJson value is a stringified array where each element follows the same schema as a single send() invocation—typically containing command, path, and props keys.
According to the implementation in sdk/node/index.js (lines 19‑22), the method signature defaults force to true and accepts an optional stopOnError boolean:
{
batchJson: JSON.stringify([
{ command: "set", path: "/Sheet1/A1", props: { text: "Hello" } },
{ command: "set", path: "/Sheet1/B2", props: { number: 123 } }
]),
force: true,
stopOnError: false
}
This structure allows the resident Office process to deserialize the entire workload before execution begins, ensuring atomic preparation of the command queue.
Single Round-Trip Execution
Once serialized, the payload travels through the private _cmd('batch', …) helper, which delegates to the low-level rpc() function. As documented in the file header (lines 5‑9), both send() and batch() utilize the same transport mechanism: writing one request line to the resident’s named pipe and awaiting a response envelope.
This architecture mirrors the CLI’s officecli batch command, eliminating the overhead of process creation for every cell update or range formatting operation. The resident maintains state across the batch, applying each command sequentially within the same workbook context.
Handling Locked Files with the Force Option
By default, batch() passes force: true, instructing the resident to apply changes even if the target file is currently locked by another application. This corresponds to the CLI’s --force flag and prevents transient lock contention from blocking automation pipelines. Developers can override this by explicitly setting force: false in the options object if strict concurrency control is required.
Error Handling Strategies
OfficeCLI distinguishes between transport-level failures (pipe disconnection, timeouts) and logical command failures (invalid cell references, type mismatches). The stopOnError flag determines how the resident handles individual command errors within the batch.
Continue on Error (stopOnError: false)
When stopOnError is omitted or set to false (the default), the resident processes the entire command list regardless of individual failures. It returns a combined envelope where the top-level success field reflects overall completion, while per-command errors populate the Stdout and Stderr fields. This mode maximizes throughput and allows post-hoc analysis of which specific indices failed.
Abort on First Failure (stopOnError: true)
Setting stopOnError: true causes the resident to terminate batch execution immediately upon encountering the first failing command. The response envelope returned at this point contains an error state, and subsequent commands in the array remain unprocessed. This strict mode is useful when operations have strict dependencies—such as inserting a row before writing to it—and partial completion would leave the workbook in an inconsistent state.
Note that the SDK surface throws OfficeCliError only when the transport itself fails (e.g., pipe connection problems or resident crash). Logical command failures remain inside the returned envelope regardless of the stopOnError setting.
Transport-Level Reliability
Both send() and batch() rely on the rpc() function defined around lines 88‑98 in sdk/node/index.js. This implementation provides:
- Bounded connect timeout: Controlled by
BUSY_CONNECT_TIMEOUT_MSto prevent indefinite hangs - Configurable retry logic:
BUSY_MAX_RETRIESwith backoff for busy pipes - Transparent resident restart: Automatically respawns the resident process if it dies mid-batch
- Single retry for busy pipes: Attempts immediate reconnection before escalating
If the resident cannot be reached after exhausting retries, rpc() throws OfficeCliError, which propagates out of batch() as a rejected promise. This distinction allows calling code to catch infrastructure failures separately from application-level validation errors.
Parsing Batch Results
The raw response line returned by rpc() is parsed by parseEnvelope() (referenced but not shown in the excerpt), extracting ExitCode, Stdout, and Stderr. The batch() method returns this envelope directly, enabling inspection of per-command results when stopOnError is disabled. Developers should check result.ExitCode and parse result.Stdout to determine individual operation success within the batch array.
Practical Example: Executing Multiple Cell Updates
The following example demonstrates opening a workbook, preparing several set commands, and executing them atomically with default error isolation:
const oc = require('@officecli/sdk');
(async () => {
// Open an existing workbook
const doc = await oc.open('budget.xlsx');
// Prepare several commands
const ops = [
{ command: 'set', path: '/Sheet1/B2', props: { number: 123 } },
{ command: 'set', path: '/Sheet1/C2', props: { number: 456 } },
{ command: 'set', path: '/Sheet1/D2', props: { number: 789 } },
];
// Execute them in one batch; stopOnError defaults to false
const result = await doc.batch(ops);
console.log('Batch envelope:', result);
// Inspect individual outcomes via result.Stdout/Stderr
if (result.ExitCode !== 0) {
console.error('One or more commands failed:', result.Stderr);
}
await doc.close();
})();
To enforce strict sequential integrity where a failure in cell B2 prevents writing to C2 and D2, pass { stopOnError: true } as the second argument to batch().
Summary
- Batch Mode in OfficeCLI serializes command arrays into a JSON envelope via
batch(items, options)insdk/node/index.js(lines 19‑22). - Single round-trip execution sends the payload through
_cmd('batch', …)andrpc(), avoiding per-command process spawning (lines 5‑9). - Force option defaults to
true, allowing writes to locked files unless explicitly disabled. - Error handling operates at two levels: transport failures raise
OfficeCliError, while command failures respect thestopOnErrorflag—either collecting all errors or aborting immediately (lines 19‑21, 88‑98). - Result inspection requires parsing the returned envelope’s
ExitCode,Stdout, andStderrto determine per-operation success when continuing past individual failures.
Frequently Asked Questions
What happens if one command in an OfficeCLI batch fails?
When stopOnError is false (the default), the resident continues processing subsequent commands and returns a combined envelope containing all results. Individual failures appear in the Stderr or Stdout fields, allowing you to identify which array indices failed after the batch completes.
Does OfficeCLI batch mode require force=true to work with locked files?
While not strictly required, force defaults to true in the batch() method, automatically overriding file locks. If you set force: false, the batch will fail if the target workbook is open in another application, matching standard CLI behavior without the --force flag.
How does OfficeCLI handle transport failures during batch execution?
The rpc() function implements BUSY_CONNECT_TIMEOUT_MS and BUSY_MAX_RETRIES with backoff logic (lines 88‑98). If the resident pipe is unreachable after retries, rpc() throws OfficeCliError, which propagates through batch() as a rejection. This indicates infrastructure failure rather than command validation errors.
Can I mix different command types in a single OfficeCLI batch?
Yes. The batchJson array accepts heterogeneous command objects—such as set, get, insert, or delete—each with distinct path and props configurations. The resident processes them sequentially in the order provided, respecting the global stopOnError policy for the entire set.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →