From 3859d9d555bc218c30e8da2f46ed2c77e53967a9 Mon Sep 17 00:00:00 2001 From: Shawn Date: Tue, 2 Jun 2026 18:09:03 -0400 Subject: [PATCH] =?UTF-8?q?fix:=20barcode=20scanner=20=E2=80=94=20hints=20?= =?UTF-8?q?not=20applied,=20per-frame=20errors=20killing=20scanner?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Root cause #1: BrowserMultiFormatReader constructor takes 0 args so hints and timing options (passed as args) were silently ignored. Hints are now applied as reader.reader.hints, and timing as instance properties. Root cause #2: ZXing per-frame 'no barcode' exceptions have message=undefined causing .toLowerCase() to crash in old message-text filter. Switched to instanceof checks against NotFoundException, ChecksumException, FormatException which properly distinguishes normal 'no barcode' frames from real errors. Tested in browser — hint setting and error filtering both verified working. --- static/index.html | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/static/index.html b/static/index.html index 7eed1e0..574a532 100644 --- a/static/index.html +++ b/static/index.html @@ -2885,7 +2885,12 @@ if (!video) return; // Create reader with 1D-only hints for fast, accurate scanning - codeReader = new ZXing.BrowserMultiFormatReader(_barcodeHints(), _barcodeOptions()); + // NOTE: BrowserMultiFormatReader constructor takes 0 args — hints and options + // must be set as instance properties for them to take effect. + codeReader = new ZXing.BrowserMultiFormatReader(); + codeReader.reader.hints = _barcodeHints(); + codeReader.timeBetweenScansMillis = 2000; // delayBetweenScanSuccess + codeReader._timeBetweenDecodingAttempts = 300; // delayBetweenScanAttempts // Pick the rear-facing camera (environment-facing on phones) let deviceId = null; @@ -2927,8 +2932,13 @@ handleBarcode(val.trim()); } } else if (err && scanningActive) { - const msg = (err.message || err || '').toLowerCase(); - if (!msg.includes('multiformat') && !msg.includes('unable to detect')) { + // NotFoundException, ChecksumException, FormatException are normal + // "no barcode on this frame" results — silently continue scanning. + // We use instanceof because ZXing's minified exception classes all + // have message="undefined", making message-text filtering unreliable. + if (!(err instanceof ZXing.NotFoundException || + err instanceof ZXing.ChecksumException || + err instanceof ZXing.FormatException)) { console.error('ZXing camera error:', err); handleCameraError(new Error(err.message || err)); }