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)); }