Errors and recovery
Choose the right channel
| Channel | Argument | Meaning |
|---|---|---|
| serial:error | Error | serial-core connection, handshake, parser-stream or port failure |
| serial:jsd-error | string | Invalid frame or exhausted JSD retries |
| serial:jsd-nack | parsed frame | Device negative acknowledgement |
| *:wrong-cmd | object | Rejected command format, with opcode and parameters |
| vision:jsd-license-error | object | License or price-control restriction |
| mdbCardHolder:jsd-license-error | object | MDB license or price-control restriction |
| licensing:report | object | License activation result, including failure reason |
| Rejected method promise | Error | Local operation precondition failed |
| JSD session ended; operation outcome may be unknown | Error | Session terminated; unfinished domain operations were rejected, not replayed |
jsd.on('serial:error', err => console.error('Transport', err.message));
jsd.on('serial:jsd-error', message => console.error('Protocol', message));
jsd.on('serial:jsd-nack', frame => console.error('NACK', frame.id));
jsd.on('vision:wrong-cmd', data => console.error(data.opcodeName, data.params));
jsd.on('vision:jsd-license-error', data => console.error(data.type, data.actionName));Parser and timeout messages
| Exact message | Interpretation and action |
|---|---|
| Frame too short | Empty decoded frame; inspect parser boundaries |
| CRC mismatch | Corrupt bytes, wrong serial settings, or incompatible framing |
| Unknown code | Valid CRC but unsupported transport code |
| JConnect header too short | DATA frame lacks its six-byte application header |
| No response for packet ID … after 3 attempts. | JSD exhausted retries; inspect connectivity and ACK IDs |
The timeout text says three attempts; implementation sends once and retries up to three times. serial:message carries raw bytes for diagnosing invalid frames. Empty raw buffers are ignored entirely.
serial-core can also emit Connection failure: …, including a missing device, an occupied port, or Handshake timeout (pattern: …). These are transport diagnostics rather than a stable, exhaustive list of JSD error codes.
Local preconditions
assignChannels():Channel assignment already in progress.requestLogs():Already fetching logs.- Channel dispense and extended dispense:
Machine N is not available to dispense. - MDB feature configuration requires a disabled card holder.
- MDB sale approval requires status
on hold; an enabled device can produce an additional always-idle diagnostic. - MDB sale approval and cash recording require amount greater than 0 and at most 65535; supplied product IDs must be numeric and at most 65535.
- Invalid MDB device selection:
Configuration for device number N not found..
The constructor also validates core 0.3.0 selectors, timer ranges, retry policy, queue capacity and parser/parserFactory exclusivity. Invalid construction throws synchronously. JSD backlog overflow throws JSD queue capacity exceeded; invalid ACK deadlines throw JSD timeout must be positive, finite and within the timer limit.
Catch rejected method promises. Payloads for domain failures remain events even when command submission succeeded.
License failures
type is expired-license, app-number-not-licensed, price-control-active-direct-dispense-not-allowed, or unknown. Activation reports distinguish incorrect format, mismatched device identity, and a counter mismatch or reused file. Correct the license before resubmitting.
Bound long-running operations
function withDeadline<T>(operation: Promise<T>, ms: number): Promise<T> {
let timer: ReturnType<typeof setTimeout>;
const timeout = new Promise<never>((_, reject) => {
timer = setTimeout(() => reject(new Error('Application deadline exceeded')), ms);
});
return Promise.race([operation, timeout]).finally(() => clearTimeout(timer));
}
const logs = await withDeadline(jsd.manifest.requestLogs(), 30_000);A deadline only stops waiting: it does not cancel queued commands, timers, or the physical operation. After an ambiguous dispense/payment result, reconcile device state before deciding whether to retry. Reissuing a physical operation can repeat it.