Skip to content

Print failures show generic "Print failed" message, hiding the real diagnostic already computed server-side #532

Description

@itsbkm

Bug description

The generic error "Print failed. Check printer connection and settings." is the #1 support complaint, and it fires on essentially every backend print failure regardless of the actual cause (network timeout, printer offline, out of paper, wrong OS queue name, spooler error, etc.) — because the specific, already-computed diagnostic is discarded before it reaches the user.

Root cause

printReceiptDetailed() (main/printers/thermal.ts:700) builds a detailed PrintResult with a human-readable detail string and a classified failureClass (see classifyPrintFailure(), main/printers/thermal.ts:69-82, and DescribeBlockingState, main/printers/thermal.ts:1867-1877) — e.g. "cannot open printer 'POS-58' (Win32 error 1801)", "Timed out connecting to 192.168.1.50:9100", "printer is out of paper".

That detail never makes it into the API response for the two routes that matter most:

  • main/routes/printers.ts:485 (/print-bill):
    res.status(502).json({ error: 'Print failed. Check printer connection and settings.', code: result.code, correlation_id: result.correlationId, stage: result.stage });
  • main/routes/printers.ts:621 (/print-kot, same pattern — "KOT print failed. Check printer connection.")

Compare with /printers/:id/test (main/routes/printers.ts:321), which correctly surfaces it:

res.status(502).json({ error: result.detail || 'Printer did not respond or print failed', detail: result.detail });

On the frontend, orders/page.tsx handlePrint (~line 587) also just does catch { toast.error(tOrders('printReceiptFailed')); } without reading err.response.data.error, so even if the backend sent more, today's UI wouldn't show it.

Net effect: a cashier sees the same unhelpful toast whether the printer is unplugged, out of paper, offline on the network, or misconfigured — with no way to self-diagnose, driving repeat support tickets for what are often trivial fixes (paper out, cable loose).

Windows-specific contributing factor: printViaUSBWindows() (main/printers/thermal.ts:1997-2040) JIT-compiles a C# helper via powershell -EncodedCommand / Add-Type -TypeDefinition on every print job (main/printers/thermal.ts:1804-1973) with only a 20s timeout (main/printers/thermal.ts:2017). On locked-down/AV-scanned POS terminals this can be slow enough to time out under normal conditions, adding to the volume of generic failures.

Proposed fix

  1. Include detail and failureClass in the /print-bill and /print-kot error responses, mirroring the /test endpoint (main/routes/printers.ts:485, 621).
  2. Update frontend print-failure handlers (orders/page.tsx handlePrint and the KOT print paths in usePrinter.ts) to surface err.response.data.detail in the toast when present, falling back to the generic message only when no detail exists.
  3. (Follow-up, lower priority) Investigate raising or making configurable the 20s Windows print timeout, or caching the compiled C# helper across print jobs instead of recompiling per job.

Related: #<ISSUE_3_NUMBER> (manually-added printers whose name doesn't match the OS queue produce this same generic error on every print, not just the initial test — this issue's fix will make that failure mode diagnosable too).

Environment

Reported by multiple users across Windows/macOS/Linux installs; this is the most common printer-related support complaint.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area:backendBackend (Express/SQLite)area:frontendFrontend (React/Next.js)bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions