# Manejo de errores en el pipeline AEAT QR de VeriFactu con IronBarcode en C#
> **Errores en la codificación fiscal española:** Al generar el QR obligatorio de AEAT para VeriFactu, los errores más frecuentes son: formato de NIF inválido, URL excesivamente larga para la versión QR configurada (se requiere mínimo Versión 4), hash `huella` ausente o mal codificado, y errores de firma en el XML de TicketBAI. Los mensajes de error detallados de IronBarcode permiten al equipo de desarrollo fiscal diagnosticar y corregir estos problemas antes de que la factura sea rechazada por el endpoint de verificación de la AEAT.
Los procesos de procesamiento de BarCodes pueden fallar de forma silenciosa, y la ausencia de resultados a menudo se confunde con "no hay BarCode presente". Sin embargo, problemas como archivos dañados, archivos PDF protegidos con contraseña o incompatibilidades de formato pueden ser los responsables. La implementación de un registro adecuado y una gestión estructurada de los errores permite detectar estos fallos y proporciona diagnósticos útiles.
IronBarcode ofrece una jerarquía de excepciones tipada en el espacio de nombres `IronBarCode.Exceptions`, una API de registro incorporada y propiedades detalladas `BarcodeResult`. Estas propiedades incluyen el formato detectado, el valor descodificado, el número de página y las coordenadas de cada descodificación correcta.
Este tutorial explica cómo capturar e interpretar excepciones tipadas, extraer el contexto de diagnóstico de lecturas fallidas, habilitar registros estructurados y aislar fallos durante operaciones en lote.
*as-heading:2(Inicio rápido: Manejar errores de código de barras y habilitar diagnósticos)*
Envuelva las llamadas de lectura/escritura en bloques try-catch dirigidos a las excepciones tipificadas de IronBarcode para resaltar mensajes de error procesables en lugar de fallos silenciosos.
```cs
:title=Handle Barcode Errors and Enable Diagnostics
using IronBarCode;
using IronBarCode.Exceptions;
try
{
BarcodeResults results = BarcodeReader.Read("label.pdf");
Console.WriteLine($"Found {results.Count} barcode(s)");
}
catch (IronBarCodeFileException ex)
{
Console.Error.WriteLine($"File error: {ex.Message}");
}
```
<div class="hsg-featured-snippet">
<h2>Cómo gestionar los errores de BarCode y habilitar el diagnóstico con IronBarcode</h2>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://nuget.org/packages/BarCode/">Descargar la biblioteca IronBarcode desde NuGet</a></li>
<li>Envuelva las llamadas de lectura/escritura en bloques try-catch dirigidos a tipos de excepciones específicas</li>
<li>Inspeccione <code>BarcodeResults</code> para entradas vacías o de baja confianza después de una lectura exitosa</li>
<li>Habilite <code>IronSoftware.Logger</code> para capturar la salida de diagnóstico interno</li>
<li>Aísle fallos por archivo en operaciones por lotes con lógica de continuar ante errores</li>
</ol>
</div>
## ¿Cómo puedo detectar e interpretar las excepciones de IronBarcode?
Captura las excepciones de IronBarcode, desde las más específicas hasta las más generales. Ordena los bloques catch para gestionar primero las excepciones procesables, como los errores de archivo, de contraseña de PDF y de codificación, seguidos del tipo base. El espacio de nombres `IronBarCode.Exceptions` define 11 tipos de excepciones, cada uno correspondiente a un modo de falla específico:
<div class="content__data-table" data-content-table>
<table>
<caption>Tipos de excepciones de IronBarcode - Causas y soluciones recomendadas</caption>
<thead>
<tr><th>Tipo de excepción</th><th>Desencadenante</th><th>Solución recomendada</th></tr>
</thead>
<tbody>
<tr><td><code>IronBarCodeFileException</code></td><td>El archivo está dañado, bloqueado o tiene un formato de imagen no compatible</td><td>Comprueba que el archivo tenga un formato de imagen compatible y que no esté bloqueado; además, detecta por separado <code>las excepciones FileNotFoundException</code> para los archivos que falten.</td></tr>
<tr><td><code>IronBarCodePdfPasswordException</code></td><td>PDF protegido por contraseña o encriptado</td><td>Suministre la contraseña a través de <code>PdfBarcodeReaderOptions</code>, o salte el archivo y registre</td></tr>
<tr><td><code>IronBarCodeEncodingException</code></td><td>Fallo genérico de codificación durante la generación de código de barras</td><td>Verifique que los datos de entrada coincidan con las restricciones de <code>BarcodeWriterEncoding</code> objetivo</td></tr>
<tr><td><code>IronBarCodeContentTooLongEncodingException</code></td><td>El valor excede el límite de caracteres para la simbología seleccionada</td><td>Trunque los datos o cambie a un formato de mayor capacidad (QR, DataMatrix)</td></tr>
<tr><td><code>IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException</code></td><td>Caracteres no numéricos pasados a un formato de solo numérico (EAN, UPC)</td><td>Limpie la entrada o cambie a un formato alfanumérico (Code128, Code39)</td></tr>
<tr><td><code>IronBarCodeUnsupportedRendererEncodingException</code></td><td>La codificación seleccionada <code>BarcodeEncoding</code> no es escribible por IronBarcode</td><td>Use el enumerador <code>BarcodeWriterEncoding</code> en lugar de <code>BarcodeEncoding</code></td></tr>
<tr><td><code>IronBarCodeParsingException</code></td><td>Los datos estructurados (GS1-128) fallan en la validación durante el análisis</td><td>Valide la estructura GS1 con <code>Code128GS1Parser.IsValid()</code> antes de analizar</td></tr>
<tr><td><code>IronBarCodeNativeException</code></td><td>Error en la capa de interoperabilidad nativa (DLLs faltantes, incompatibilidad de plataforma)</td><td>Verifique que los paquetes específicos de la plataforma NuGet estén instalados (BarCode.Linux, BarCode.macOS)</td></tr>
<tr><td><code>IronBarCodeConfidenceThresholdException</code></td><td>Argumento de umbral de confianza inválido pasado a opciones de lector</td><td>Asegúrese de que <code>ConfidenceThreshold</code> esté entre 0.0 y 1.0</td></tr>
<tr><td><code>IronBarCodeUnsupportedException</code></td><td>Operación no soportada en el contexto actual</td><td>Consulte el <a href="https://ironsoftware.com/csharp/barcode/product-updates/changelog/">registro de cambios</a> para disponibilidad de características en su versión</td></tr>
<tr><td><code>IronBarCodeException</code></td><td>Tipo base - captura cualquier error específico de IronBarcode no coincidente arriba</td><td>Registre los detalles completos de la excepción y escale para la investigación</td></tr>
</tbody>
</table>
</div>
Utilice filtros de excepciones con cláusulas `when` para encaminar tipos de excepciones superpuestas sin anidamiento profundo. Los archivos faltantes lanzan la `System.IO.FileNotFoundException` estándar en lugar de `IronBarCodeFileException`, así que incluya un bloque de captura separado para este caso:
### Entrada
Un BarCode Code128 que codifica un número de factura (ruta de éxito) y un BarCode de etiqueta de almacén que representa el contenido del PDF que falta (ruta de error).
<div class="competitors-section__wrapper-even-1">
<div class="competitors__card" style="width: 45%;">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-invoice.png"
alt="Codificación de BarCode Code128 INV-2024-7829 utilizada como entrada de factura escaneada"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
scanned-invoice.png (ruta de éxito)
</p>
</div>
<div class="competitors__card" style="width: 45%;">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-warehouse-labels.png"
alt="Código de barras Code128 que representa el contenido de la entrada de la ruta de fallo del archivo warehouse-labels.pdf faltante"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
warehouse-labels.PDF (ruta de error: archivo no presente en el disco)
</p>
</div>
</div>
```cs
using IronBarCode;
using IronBarCode.Exceptions;
// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";
try
{
BarcodeResults results = BarcodeReader.Read(filePath);
foreach (BarcodeResult result in results)
{
// Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
}
}
catch (IronBarCodePdfPasswordException ex)
{
// PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
// File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
// Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
// The when filter routes only missing-DLL errors here; other native exceptions
// fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
// Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
```
### Resultado
[[i:(Un archivo válido se resuelve en el tipo y el valor del BarCode descodificado.)]]
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-exception-hierarchy-success.webp" alt="Salida de la consola que muestra la decodificación correcta de Code128: [Code128] INV-2024-7829" class="img-responsive add-shadow" />
</div>
</div>
Un archivo faltante dispara `FileNotFoundException`, dirigido por el bloque de captura dedicado.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-exception-hierarchy-failure.webp" alt="Salida de la consola que muestra una excepción FileNotFoundException por la falta del archivo warehouse-labels.PDF" class="img-responsive add-shadow" />
</div>
</div>
El filtro `when (ex.Message.Contains("DLL"))` en `IronBarCodeNativeException` direcciona los errores de dependencia faltante a un manejador específico sin afectar otras excepciones nativas. Este enfoque resulta especialmente útil en implementaciones de Docker, donde pueden faltar paquetes específicos de la plataforma.
`IronSoftware.Exceptions.LicensingException` se lanza por separado cuando la clave de licencia es inválida o falta. Detecta esta excepción al inicio de la aplicación en lugar de en cada llamada de lectura o escritura individual.
---
## ¿Cómo extraigo los detalles de diagnóstico de las lecturas fallidas?
Una operación de lectura que devuelve cero resultados no es una excepción; produce una colección `BarcodeResults` vacía. El contexto de diagnóstico se obtiene inspeccionando los parámetros de entrada, las opciones configuradas y cualquier resultado parcial devuelto.
El objeto `BarcodeResult` proporciona propiedades útiles para el análisis post-mortem, incluyendo `BarcodeType`, `Value`, `PageNumber`, y `Points` (coordenadas de esquina). Si los resultados están presentes pero son inesperados, primero verifique `BarcodeType` contra el formato esperado y verifique el `PageNumber`.
### Entrada
Un código de barras Code128 que codifica un número de factura, leído con `ExpectBarcodeTypes` configurado a `Code128` y `QRCode`, y `ReadingSpeed.Detailed` para un escaneo exhaustivo.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-invoice.png" alt="Codificación de BarCode Code128 INV-2024-7829 utilizada como entrada de factura escaneada" class="img-responsive add-shadow" />
</div>
</div>
```cs
using IronBarCode;
string filePath = "scanned-invoice.png";
// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
Speed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged images
ExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match
};
BarcodeResults results = BarcodeReader.Read(filePath, options);
// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
// Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");
Console.Error.WriteLine($" Speed: {options.Speed}");
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
foreach (BarcodeResult result in results)
{
// Points contains the four corner coordinates of the barcode in the image;
// use the first corner as a representative position indicator
string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
+ $"(Page: {result.PageNumber}, Position: {pos})");
}
}
```
### Resultado
Cuando `ExpectBarcodeTypes` coincide con el código de barras en la imagen, la lectura devuelve el tipo, valor, número de página y posición.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-diagnostic-logging-success.webp" alt="Salida de consola que muestra la decodificación correcta de Code128 con el número de página y las coordenadas de posición" class="img-responsive add-shadow" />
</div>
</div>
Si `ExpectBarcodeTypes` no incluye la simbología actual, la lectura devuelve un resultado vacío. El bloque [WARN] registra los tipos configurados, la velocidad de lectura y una sugerencia de acción a seguir.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-diagnostic-logging-failure.webp" alt="Salida de la consola que muestra [WARN] no se han encontrado BarCodes con ExpectBarcodeTypes establecido en Code39 para una imagen Code128" class="img-responsive add-shadow" />
</div>
</div>
Durante el diagnóstico surgen dos patrones comunes. Los resultados vacíos con una configuración `ExpectBarcodeTypes` estrecha a menudo significan que el código de barras utiliza una simbología diferente; expandir a `BarcodeEncoding.All` puede confirmar esto. Los resultados de decodificación inesperados suelen indicar una mala calidad de la imagen.
Aplicar filtros de imagen y volver a intentarlo con una velocidad de lectura más lenta suele resolver estos problemas. También puede activar la opción `RemoveFalsePositive` para eliminar lecturas fantasma de fondos ruidosos.
## ¿Cómo activo el registro detallado para las operaciones con BarCodes?
IronBarcode expone una API de registro incorporada a través de `IronSoftware.Logger`. Configure el modo de registro y la ruta del archivo antes de realizar cualquier operación con BarCodes para capturar la salida de diagnóstico interna de los procesos de lectura y escritura.
### Entrada
Una imagen TIFF de BarCode Code128 utilizada como objetivo de lectura mientras el registro detallado está activo.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-problem-scan.png" alt="Codificación de BarCode Code128 PROB-SCAN-999 utilizada como entrada de escaneo de prueba para el ejemplo de registro" class="img-responsive add-shadow" />
</div>
</div>
```cs
using IronBarCode;
// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory
// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Detailed,
ExpectBarcodeTypes = BarcodeEncoding.All // scan for every supported symbology
};
BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
```
`LoggingModes.All` captura tanto la salida de depuración como el registro a nivel de archivo. El archivo de registro recoge los pasos de procesamiento internos, como las etapas de preprocesamiento de imágenes, los intentos de detección de formato y las llamadas de interoperabilidad nativas, que no son visibles a través de la API pública.
Para líneas de producción que utilizan un marco de registro estructurado (Serilog, NLog, `Microsoft.Extensions.Logging`), envolver las operaciones de IronBarcode en una capa de middleware añade entradas JSON estructuradas junto al archivo de registro incorporado. El registrador incorporado escribe diagnósticos en texto plano útiles para la escalación de soporte; El contenedor estructurado proporciona campos consultables para la pila de observabilidad.
```cs
using IronBarCode;
using System.Diagnostics;
// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
try
{
BarcodeResults results = BarcodeReader.Read(filePath, options);
sw.Stop();
// Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
+ $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
return results;
}
catch (Exception ex)
{
sw.Stop();
// Emit a structured error entry to stderr with exception type, message, and elapsed time
Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
+ $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
+ $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
throw; // rethrow so the caller's catch blocks still handle the exception normally
}
}
```
El resultado estructurado se integra directamente con herramientas de agregación de registros. Conduzca `stdout` a Fluentd, Datadog o CloudWatch en un despliegue containerizado. El campo de tiempo transcurrido destaca las regresiones de rendimiento antes de que se conviertan en incumplimientos del SLA.
### Resultado
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-enable-logging.webp" alt="Salida de la consola que muestra una lectura correcta del BarCode con el registro detallado habilitado y la ruta del archivo de registro" class="img-responsive add-shadow" />
</div>
</div>
---
## ¿Cómo depuro el procesamiento por lotes de BarCodes?
Procesa varios archivos aislando cada lectura en su propio bloque try-catch, registrando los resultados de cada archivo y generando un resumen agregado. El proceso continúa a pesar de los fallos, en lugar de detenerse ante el primer error.
### Entrada
Cuatro de las cinco imágenes de código de barras Code128 del directorio de lote `scans/`. El quinto archivo (`scan-05-broken.png`) contiene bytes inválidos para activar una excepción de archivo.
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-one.png"
alt="Code128 barcode encoding ITEM-SQ-001"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Lote 1 - Escaneo 1</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-two.png"
alt="Code128 barcode encoding ITEM-SQ-002"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Lote 1 - Escaneo 2</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-three.png"
alt="Code128 barcode encoding ITEM-SQ-003"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Lote 1 - Escaneo 3</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-four.png"
alt="Code128 barcode encoding ITEM-SQ-004"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Lote 1 - Escaneo 4</p>
</div>
</div>
</div>
```cs
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;
// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";
// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced, // balances throughput vs accuracy
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
ExpectMultipleBarcodes = true // scan each file fully
};
// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();
foreach (string file in files)
{
try
{
BarcodeResults results = BarcodeReader.Read(file, options);
// Empty result is not an exception — the file was read but contained no matching barcode
if (results == null || results.Count == 0)
{
emptyCount++;
errors.Add((file, "No barcodes detected")); // record so caller can adjust options
continue;
}
foreach (BarcodeResult result in results)
{
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
}
successCount++;
}
catch (IronBarCodePdfPasswordException)
{
// PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount++;
errors.Add((file, "Password-protected PDF"));
}
catch (IronBarCodeFileException ex)
{
// File is corrupted, locked, or in an unsupported image format
failCount++;
errors.Add((file, $"File error: {ex.Message}"));
}
catch (FileNotFoundException ex)
{
// File was in the directory listing but deleted before the read completed (race condition)
failCount++;
errors.Add((file, $"File not found: {ex.Message}"));
}
catch (IronBarCodeException ex)
{
// Catch-all for any other IronBarcode-specific errors not handled above
failCount++;
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
}
catch (Exception ex)
{
// Unexpected non-IronBarcode error — log the full type for investigation
failCount++;
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
}
}
sw.Stop();
// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files: {files.Length}");
Console.WriteLine($"Success: {successCount}");
Console.WriteLine($"Empty reads: {emptyCount}");
Console.WriteLine($"Failures: {failCount}");
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");
if (errors.Any())
{
Console.WriteLine("\n--- Error Details ---");
foreach (var (errorFile, errorMsg) in errors)
{
Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}");
}
}
```
### Resultado
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-batch-processing.webp" alt="Salida de la consola que muestra el resumen del lote: 4 éxitos, 1 fallo, con detalles del error del archivo dañado" class="img-responsive add-shadow" />
</div>
</div>
Durante la ejecución, la consola muestra una línea por cada BarCode descodificado, seguida de un resumen con el recuento de archivos, los éxitos, las lecturas vacías, los fallos y el tiempo transcurrido. Los errores se enumeran con sus correspondientes nombres de archivo y los motivos del fallo.
El proceso distingue tres categorías de resultados: éxito (BarCodes encontrados y descodificados), vacío (archivo leído pero sin BarCodes detectados) y fallo (excepción lanzada). Esta distinción es importante porque las lecturas vacías y los errores requieren respuestas diferentes. Las lecturas vacías pueden requerir ajustes de formato más amplios, mientras que los errores suelen indicar problemas de infraestructura, como archivos que faltan, recursos bloqueados o dependencias nativas que faltan.
La lista de errores mantiene el contexto de cada archivo para facilitar el análisis de la causa raíz. En un pipeline de CI/CD, analice esta salida para establecer códigos de salida (cero para éxito completo y no cero cuando `failCount` es mayor que cero) o reenvíe detalles de error a un sistema de alertas.
Para un mayor rendimiento, habilite el procesamiento en paralelo configurando `Multithreaded` a `true` y ajustando `MaxParallelThreads` para que coincida con los núcleos de CPU disponibles. Mantenga la aislamiento por archivo envolviendo la iteración en paralelo en `Parallel.ForEach` y utilizando una colección segura para hilos para la lista de errores.
---
## Más información
- [Tutoriales de IronBarcode: Lectura de BarCodes](https://ironsoftware.com/csharp/barcode/tutorials/reading-barcodes/): guías paso a paso de lectura de extremo a extremo.
- [Prevención de falsos positivos](https://ironsoftware.com/csharp/barcode/troubleshooting/false-positives/): reducción de lecturas fantasma en imágenes con ruido.
- [Guía práctica de corrección de imágenes](https://ironsoftware.com/csharp/barcode/how-to/image-correction/): filtros que mejoran la precisión de lectura.
- [Guía de configuración de Docker](https://ironsoftware.com/csharp/barcode/get-started/docker-linux/): implementación en contenedores con las dependencias nativas correctas.
- [Referencia de la API de BarcodeReaderOptions](https://ironsoftware.com/csharp/barcode/object-reference/api/IronBarCode.BarcodeReaderOptions.html): documentación completa de configuración.
- [Registro de cambios de IronBarcode](https://ironsoftware.com/csharp/barcode/product-updates/changelog/): correcciones específicas de la versión y nuevas funciones.
[Consulte las opciones de licencia](https://ironsoftware.com/csharp/barcode/licensing/) cuando el proceso esté listo para la producción.
## Diagnóstico de errores en el pipeline fiscal español
Los sistemas de facturación electrónica española presentan patrones de error específicos que el sistema de excepciones de IronBarcode ayuda a resolver:
**Errores en la generación del QR de AEAT (VeriFactu):** La excepción `IronBarCodeContentTooLongEncodingException` indica que la URL de AEAT supera la capacidad de la versión QR configurada. La URL completa de `sede.agenciatributaria.gob.es` con los cinco parámetros suele requerir QR Versión 4 o superior. Solución: no limitar la versión QR manualmente y dejar que IronBarcode la seleccione automáticamente.
**Errores de codificación URL:** Si el parámetro `nif` contiene caracteres no válidos (p. ej., letras minúsculas en CIF/NIF antes del escape) o el parámetro `huella` no está correctamente codificado en URL, el QR generado no superará la validación del endpoint de AEAT. Use `Uri.EscapeDataString()` antes de construir la URL y envuelva la generación en `IronBarCodeEncodingException` para capturar estos fallos.
**Errores de lectura de QR de TicketBAI:** Cuando el lector de QR devuelve una colección vacía al procesar tíquets de Bizkaia, Gipuzkoa o Araba, verifique que `ExpectBarcodeTypes` incluya `BarcodeEncoding.QRCode` y que la calidad de la imagen sea suficiente. El bloque de diagnóstico `[WARN]` registra los tipos configurados y la velocidad de lectura para facilitar la depuración.
**Procesamiento por lotes SII:** En pipelines de reconciliación del SII con cientos de facturas por lote, el patrón de aislamiento por archivo distingue entre facturas con QR válido (éxito), facturas sin QR (lectura vacía) y facturas con imagen dañada (excepción). El informe de resumen con recuentos de éxito/fallo facilita el análisis de la causa raíz antes de la comunicación a la AEAT.
Para la trazabilidad SILICIE en entornos farmacéuticos, capture `IronBarCodeFileException` al procesar imágenes de etiquetas de medicamentos escaneadas que puedan estar dañadas o tener resolución insuficiente, y registre el código de producto y lote para su reescaneo.
Errores en la codificación fiscal española: Al generar el QR obligatorio de AEAT para VeriFactu, los errores más frecuentes son: formato de NIF inválido, URL excesivamente larga para la versión QR configurada (se requiere mínimo Versión 4), hash huella ausente o mal codificado, y errores de firma en el XML de TicketBAI. Los mensajes de error detallados de IronBarcode permiten al equipo de desarrollo fiscal diagnosticar y corregir estos problemas antes de que la factura sea rechazada por el endpoint de verificación de la AEAT.
Los procesos de procesamiento de BarCodes pueden fallar de forma silenciosa, y la ausencia de resultados a menudo se confunde con "no hay BarCode presente". Sin embargo, problemas como archivos dañados, archivos PDF protegidos con contraseña o incompatibilidades de formato pueden ser los responsables. La implementación de un registro adecuado y una gestión estructurada de los errores permite detectar estos fallos y proporciona diagnósticos útiles.
IronBarcode ofrece una jerarquía de excepciones tipada en el espacio de nombres IronBarCode.Exceptions, una API de registro incorporada y propiedades detalladas BarcodeResult. Estas propiedades incluyen el formato detectado, el valor descodificado, el número de página y las coordenadas de cada descodificación correcta.
Este tutorial explica cómo capturar e interpretar excepciones tipadas, extraer el contexto de diagnóstico de lecturas fallidas, habilitar registros estructurados y aislar fallos durante operaciones en lote.
Inicio rápido: Manejar errores de código de barras y habilitar diagnósticos
Envuelva las llamadas de lectura/escritura en bloques try-catch dirigidos a las excepciones tipificadas de IronBarcode para resaltar mensajes de error procesables en lugar de fallos silenciosos.
Envuelva las llamadas de lectura/escritura en bloques try-catch dirigidos a tipos de excepciones específicas
Inspeccione BarcodeResults para entradas vacías o de baja confianza después de una lectura exitosa
Habilite IronSoftware.Logger para capturar la salida de diagnóstico interno
Aísle fallos por archivo en operaciones por lotes con lógica de continuar ante errores
¿Cómo puedo detectar e interpretar las excepciones de IronBarcode?
Captura las excepciones de IronBarcode, desde las más específicas hasta las más generales. Ordena los bloques catch para gestionar primero las excepciones procesables, como los errores de archivo, de contraseña de PDF y de codificación, seguidos del tipo base. El espacio de nombres IronBarCode.Exceptions define 11 tipos de excepciones, cada uno correspondiente a un modo de falla específico:
Tipos de excepciones de IronBarcode - Causas y soluciones recomendadas
Tipo de excepción
Desencadenante
Solución recomendada
IronBarCodeFileException
El archivo está dañado, bloqueado o tiene un formato de imagen no compatible
Comprueba que el archivo tenga un formato de imagen compatible y que no esté bloqueado; además, detecta por separado las excepciones FileNotFoundException para los archivos que falten.
IronBarCodePdfPasswordException
PDF protegido por contraseña o encriptado
Suministre la contraseña a través de PdfBarcodeReaderOptions, o salte el archivo y registre
IronBarCodeEncodingException
Fallo genérico de codificación durante la generación de código de barras
Verifique que los datos de entrada coincidan con las restricciones de BarcodeWriterEncoding objetivo
IronBarCodeContentTooLongEncodingException
El valor excede el límite de caracteres para la simbología seleccionada
Trunque los datos o cambie a un formato de mayor capacidad (QR, DataMatrix)
Caracteres no numéricos pasados a un formato de solo numérico (EAN, UPC)
Limpie la entrada o cambie a un formato alfanumérico (Code128, Code39)
IronBarCodeUnsupportedRendererEncodingException
La codificación seleccionada BarcodeEncoding no es escribible por IronBarcode
Use el enumerador BarcodeWriterEncoding en lugar de BarcodeEncoding
IronBarCodeParsingException
Los datos estructurados (GS1-128) fallan en la validación durante el análisis
Valide la estructura GS1 con Code128GS1Parser.IsValid() antes de analizar
IronBarCodeNativeException
Error en la capa de interoperabilidad nativa (DLLs faltantes, incompatibilidad de plataforma)
Verifique que los paquetes específicos de la plataforma NuGet estén instalados (BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdException
Argumento de umbral de confianza inválido pasado a opciones de lector
Asegúrese de que ConfidenceThreshold esté entre 0.0 y 1.0
IronBarCodeUnsupportedException
Operación no soportada en el contexto actual
Consulte el registro de cambios para disponibilidad de características en su versión
IronBarCodeException
Tipo base - captura cualquier error específico de IronBarcode no coincidente arriba
Registre los detalles completos de la excepción y escale para la investigación
Utilice filtros de excepciones con cláusulas when para encaminar tipos de excepciones superpuestas sin anidamiento profundo. Los archivos faltantes lanzan la System.IO.FileNotFoundException estándar en lugar de IronBarCodeFileException, así que incluya un bloque de captura separado para este caso:
Entrada
Un BarCode Code128 que codifica un número de factura (ruta de éxito) y un BarCode de etiqueta de almacén que representa el contenido del PDF que falta (ruta de error).
scanned-invoice.png (ruta de éxito)
warehouse-labels.PDF (ruta de error: archivo no presente en el disco)
using IronBarCode;using IronBarCode.Exceptions;// Success path: valid file present on diskstring filePath = "scanned-invoice.png";// Failure path: file does not exist → caught by FileNotFoundException below// string filePath = "warehouse-labels.pdf";try{ BarcodeResults results = BarcodeReader.Read(filePath); foreach (BarcodeResult result in results) { // Print the detected symbology and decoded value for each barcode foundConsole.WriteLine($"[{result.BarcodeType}] {result.Value}"); }}catch (IronBarCodePdfPasswordException ex){ // PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retryingConsole.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");}catch (IronBarCodeFileException ex){ // File is present but corrupted, locked, or in an unsupported formatConsole.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");}catch (FileNotFoundException ex){ // Missing files throw FileNotFoundException, not IronBarCodeFileExceptionConsole.Error.WriteLine($"File not found: {filePath} — {ex.Message}");}catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL")){ // The when filter routes only missing-DLL errors here; other native exceptions // fall through to the IronBarCodeException block belowConsole.Error.WriteLine($"Missing native dependency: {ex.Message}");}catch (IronBarCodeException ex){ // Base catch for any IronBarcode-specific error not matched by the blocks aboveConsole.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");}
using IronBarCode;
using IronBarCode.Exceptions;
// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";
try
{
BarcodeResults results = BarcodeReader.Read(filePath);
foreach (BarcodeResult result in results)
{
// Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
}
}
catch (IronBarCodePdfPasswordException ex)
{
// PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
// File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
// Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
// The when filter routes only missing-DLL errors here; other native exceptions
// fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
// Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
ImportsIronBarCodeImportsIronBarCode.Exceptions' Success path: valid file present on diskDim filePath AsString = "scanned-invoice.png"' Failure path: file does not exist → caught by FileNotFoundException below' Dim filePath As String = "warehouse-labels.pdf"Try Dim results AsBarcodeResults = BarcodeReader.Read(filePath) For Each result AsBarcodeResultIn results ' Print the detected symbology and decoded value for each barcode foundConsole.WriteLine($"[{result.BarcodeType}] {result.Value}") NextCatch ex AsIronBarCodePdfPasswordException ' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retryingConsole.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")Catch ex AsIronBarCodeFileException ' File is present but corrupted, locked, or in an unsupported formatConsole.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")Catch ex AsFileNotFoundException ' Missing files throw FileNotFoundException, not IronBarCodeFileExceptionConsole.Error.WriteLine($"File not found: {filePath} — {ex.Message}")Catch ex AsIronBarCodeNativeExceptionWhen ex.Message.Contains("DLL") ' The when filter routes only missing-DLL errors here; other native exceptions ' fall through to the IronBarCodeException block belowConsole.Error.WriteLine($"Missing native dependency: {ex.Message}")Catch ex AsIronBarCodeException ' Base catch for any IronBarcode-specific error not matched by the blocks aboveConsole.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")EndTry
Imports IronBarCode
Imports IronBarCode.Exceptions
' Success path: valid file present on disk
Dim filePath As String = "scanned-invoice.png"
' Failure path: file does not exist → caught by FileNotFoundException below
' Dim filePath As String = "warehouse-labels.pdf"
Try
Dim results As BarcodeResults = BarcodeReader.Read(filePath)
For Each result As BarcodeResult In results
' Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}")
Next
Catch ex As IronBarCodePdfPasswordException
' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")
Catch ex As IronBarCodeFileException
' File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")
Catch ex As FileNotFoundException
' Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}")
Catch ex As IronBarCodeNativeException When ex.Message.Contains("DLL")
' The when filter routes only missing-DLL errors here; other native exceptions
' fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}")
Catch ex As IronBarCodeException
' Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")
End Try
Resultado
Por favor nota: Un archivo válido se resuelve en el tipo y el valor del BarCode descodificado.
Un archivo faltante dispara FileNotFoundException, dirigido por el bloque de captura dedicado.
El filtro when (ex.Message.Contains("DLL")) en IronBarCodeNativeException direcciona los errores de dependencia faltante a un manejador específico sin afectar otras excepciones nativas. Este enfoque resulta especialmente útil en implementaciones de Docker, donde pueden faltar paquetes específicos de la plataforma.
IronSoftware.Exceptions.LicensingException se lanza por separado cuando la clave de licencia es inválida o falta. Detecta esta excepción al inicio de la aplicación en lugar de en cada llamada de lectura o escritura individual.
¿Cómo extraigo los detalles de diagnóstico de las lecturas fallidas?
Una operación de lectura que devuelve cero resultados no es una excepción; produce una colección BarcodeResults vacía. El contexto de diagnóstico se obtiene inspeccionando los parámetros de entrada, las opciones configuradas y cualquier resultado parcial devuelto.
El objeto BarcodeResult proporciona propiedades útiles para el análisis post-mortem, incluyendo BarcodeType, Value, PageNumber, y Points (coordenadas de esquina). Si los resultados están presentes pero son inesperados, primero verifique BarcodeType contra el formato esperado y verifique el PageNumber.
Entrada
Un código de barras Code128 que codifica un número de factura, leído con ExpectBarcodeTypes configurado a Code128 y QRCode, y ReadingSpeed.Detailed para un escaneo exhaustivo.
using IronBarCode;string filePath = "scanned-invoice.png";// Configure the reader to narrow the search to specific symbologies and use// a thorough scan pass — narrows false positives and improves decode accuracyvar options = new BarcodeReaderOptions{ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formatsSpeed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged imagesExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match};BarcodeResults results = BarcodeReader.Read(filePath, options);// An empty result is not an exception — it means no barcode matched the configured optionsif (results == null || results.Count == 0){ // Log the configured options alongside the warning so the cause is immediately actionableConsole.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");Console.Error.WriteLine($" Speed: {options.Speed}");Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");}else{ foreach (BarcodeResult result in results) { // Points contains the four corner coordinates of the barcode in the image; // use the first corner as a representative position indicator string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";Console.WriteLine($"[{result.BarcodeType}] {result.Value} " + $"(Page: {result.PageNumber}, Position: {pos})"); }}
using IronBarCode;
string filePath = "scanned-invoice.png";
// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
Speed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged images
ExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match
};
BarcodeResults results = BarcodeReader.Read(filePath, options);
// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
// Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");
Console.Error.WriteLine($" Speed: {options.Speed}");
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
foreach (BarcodeResult result in results)
{
// Points contains the four corner coordinates of the barcode in the image;
// use the first corner as a representative position indicator
string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
+ $"(Page: {result.PageNumber}, Position: {pos})");
}
}
ImportsIronBarCodeDim filePath AsString = "scanned-invoice.png"' Configure the reader to narrow the search to specific symbologies and use' a thorough scan pass — narrows false positives and improves decode accuracyDim options As New BarcodeReaderOptionsWith { .ExpectBarcodeTypes = BarcodeEncoding.Code128OrBarcodeEncoding.QRCode, ' limit scan to known formats .Speed = ReadingSpeed.Detailed, ' slower but more thorough — use ExtremeDetail for damaged images .ExpectMultipleBarcodes = True ' scan the full image rather than stopping at the first match}Dim results AsBarcodeResults = BarcodeReader.Read(filePath, options)' An empty result is not an exception — it means no barcode matched the configured optionsIf results Is NothingOrElse results.Count = 0 Then ' Log the configured options alongside the warning so the cause is immediately actionableConsole.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}")Console.Error.WriteLine($" Speed: {options.Speed}")Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")Else For Each result AsBarcodeResultIn results ' Points contains the four corner coordinates of the barcode in the image; ' use the first corner as a representative position indicator Dim pos AsString = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")Console.WriteLine($"[{result.BarcodeType}] {result.Value} " & $"(Page: {result.PageNumber}, Position: {pos})") NextEnd If
Imports IronBarCode
Dim filePath As String = "scanned-invoice.png"
' Configure the reader to narrow the search to specific symbologies and use
' a thorough scan pass — narrows false positives and improves decode accuracy
Dim options As New BarcodeReaderOptions With {
.ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit scan to known formats
.Speed = ReadingSpeed.Detailed, ' slower but more thorough — use ExtremeDetail for damaged images
.ExpectMultipleBarcodes = True ' scan the full image rather than stopping at the first match
}
Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
' An empty result is not an exception — it means no barcode matched the configured options
If results Is Nothing OrElse results.Count = 0 Then
' Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}")
Console.Error.WriteLine($" Speed: {options.Speed}")
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")
Else
For Each result As BarcodeResult In results
' Points contains the four corner coordinates of the barcode in the image;
' use the first corner as a representative position indicator
Dim pos As String = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")
Console.WriteLine($"[{result.BarcodeType}] {result.Value} " &
$"(Page: {result.PageNumber}, Position: {pos})")
Next
End If
Resultado
Cuando ExpectBarcodeTypes coincide con el código de barras en la imagen, la lectura devuelve el tipo, valor, número de página y posición.
Si ExpectBarcodeTypes no incluye la simbología actual, la lectura devuelve un resultado vacío. El bloque [WARN] registra los tipos configurados, la velocidad de lectura y una sugerencia de acción a seguir.
Durante el diagnóstico surgen dos patrones comunes. Los resultados vacíos con una configuración ExpectBarcodeTypes estrecha a menudo significan que el código de barras utiliza una simbología diferente; expandir a BarcodeEncoding.All puede confirmar esto. Los resultados de decodificación inesperados suelen indicar una mala calidad de la imagen.
Aplicar filtros de imagen y volver a intentarlo con una velocidad de lectura más lenta suele resolver estos problemas. También puede activar la opción RemoveFalsePositive para eliminar lecturas fantasma de fondos ruidosos.
¿Cómo activo el registro detallado para las operaciones con BarCodes?
IronBarcode expone una API de registro incorporada a través de IronSoftware.Logger. Configure el modo de registro y la ruta del archivo antes de realizar cualquier operación con BarCodes para capturar la salida de diagnóstico interna de los procesos de lectura y escritura.
Entrada
Una imagen TIFF de BarCode Code128 utilizada como objetivo de lectura mientras el registro detallado está activo.
using IronBarCode;// Enable IronBarcode's built-in logging — set BEFORE any read/write calls// LoggingModes.All writes both debug output and file-level diagnosticsIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory// All subsequent operations will write internal processing steps to the log file:// image pre-processing stages, format detection attempts, and native interop callsvar options = new BarcodeReaderOptions{Speed = ReadingSpeed.Detailed,ExpectBarcodeTypes = BarcodeEncoding.All// scan for every supported symbology};BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
using IronBarCode;
// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory
// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Detailed,
ExpectBarcodeTypes = BarcodeEncoding.All // scan for every supported symbology
};
BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
ImportsIronBarCode' Enable IronBarcode's built-in logging — set BEFORE any read/write calls' LoggingModes.All writes both debug output and file-level diagnosticsIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.AllIronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory' All subsequent operations will write internal processing steps to the log file:' image pre-processing stages, format detection attempts, and native interop callsDim options As New BarcodeReaderOptionsWith { .Speed = ReadingSpeed.Detailed, .ExpectBarcodeTypes = BarcodeEncoding.All' scan for every supported symbology}Dim results AsBarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
Imports IronBarCode
' Enable IronBarcode's built-in logging — set BEFORE any read/write calls
' LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory
' All subsequent operations will write internal processing steps to the log file:
' image pre-processing stages, format detection attempts, and native interop calls
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Detailed,
.ExpectBarcodeTypes = BarcodeEncoding.All ' scan for every supported symbology
}
Dim results As BarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
LoggingModes.All captura tanto la salida de depuración como el registro a nivel de archivo. El archivo de registro recoge los pasos de procesamiento internos, como las etapas de preprocesamiento de imágenes, los intentos de detección de formato y las llamadas de interoperabilidad nativas, que no son visibles a través de la API pública.
Para líneas de producción que utilizan un marco de registro estructurado (Serilog, NLog, Microsoft.Extensions.Logging), envolver las operaciones de IronBarcode en una capa de middleware añade entradas JSON estructuradas junto al archivo de registro incorporado. El registrador incorporado escribe diagnósticos en texto plano útiles para la escalación de soporte; El contenedor estructurado proporciona campos consultables para la pila de observabilidad.
using IronBarCode;using System.Diagnostics;// Lightweight wrapper that adds structured JSON observability to every read call.// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.BarcodeResultsReadWithDiagnostics(string filePath, BarcodeReaderOptions options){ var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included try { BarcodeResults results = BarcodeReader.Read(filePath, options); sw.Stop(); // Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatchConsole.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\"," + $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}"); return results; } catch (Exception ex) { sw.Stop(); // Emit a structured error entry to stderr with exception type, message, and elapsed timeConsole.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\"," + $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\"," + $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}"); throw; // rethrow so the caller's catch blocks still handle the exception normally }}
using IronBarCode;
using System.Diagnostics;
// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
try
{
BarcodeResults results = BarcodeReader.Read(filePath, options);
sw.Stop();
// Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
+ $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
return results;
}
catch (Exception ex)
{
sw.Stop();
// Emit a structured error entry to stderr with exception type, message, and elapsed time
Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
+ $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
+ $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
throw; // rethrow so the caller's catch blocks still handle the exception normally
}
}
ImportsIronBarCodeImportsSystem.Diagnostics' Lightweight wrapper that adds structured JSON observability to every read call.' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.FunctionReadWithDiagnostics(filePath AsString, options AsBarcodeReaderOptions) AsBarcodeResults Dim sw AsStopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is includedTry Dim results AsBarcodeResults = BarcodeReader.Read(filePath, options) sw.Stop() ' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatchConsole.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}") Return resultsCatch ex AsException sw.Stop() ' Emit a structured error entry to stderr with exception type, message, and elapsed timeConsole.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")Throw' rethrow so the caller's catch blocks still handle the exception normallyEndTryEnd Function
Imports IronBarCode
Imports System.Diagnostics
' Lightweight wrapper that adds structured JSON observability to every read call.
' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
Function ReadWithDiagnostics(filePath As String, options As BarcodeReaderOptions) As BarcodeResults
Dim sw As Stopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is included
Try
Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
sw.Stop()
' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
Console.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
Return results
Catch ex As Exception
sw.Stop()
' Emit a structured error entry to stderr with exception type, message, and elapsed time
Console.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
Throw ' rethrow so the caller's catch blocks still handle the exception normally
End Try
End Function
El resultado estructurado se integra directamente con herramientas de agregación de registros. Conduzca stdout a Fluentd, Datadog o CloudWatch en un despliegue containerizado. El campo de tiempo transcurrido destaca las regresiones de rendimiento antes de que se conviertan en incumplimientos del SLA.
Resultado
¿Cómo depuro el procesamiento por lotes de BarCodes?
Procesa varios archivos aislando cada lectura en su propio bloque try-catch, registrando los resultados de cada archivo y generando un resumen agregado. El proceso continúa a pesar de los fallos, en lugar de detenerse ante el primer error.
Entrada
Cuatro de las cinco imágenes de código de barras Code128 del directorio de lote scans/. El quinto archivo (scan-05-broken.png) contiene bytes inválidos para activar una excepción de archivo.
Lote 1 - Escaneo 1
Lote 1 - Escaneo 2
Lote 1 - Escaneo 3
Lote 1 - Escaneo 4
using IronBarCode;using IronBarCode.Exceptions;using System.Diagnostics;// Enable built-in logging for the entire batch run so internal processing steps// are captured in the log file alongside the per-file console outputIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;IronSoftware.Logger.LogFilePath = "batch-run.log";// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectoriesstring[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);var options = new BarcodeReaderOptions{Speed = ReadingSpeed.Balanced, // balances throughput vs accuracyExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formatsExpectMultipleBarcodes = true // scan each file fully};// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)int successCount = 0;int failCount = 0;int emptyCount = 0;var errors = new List<(stringFile, stringError)>(); // per-file error context for root cause analysisvar sw = Stopwatch.StartNew();foreach (string file in files){ try { BarcodeResults results = BarcodeReader.Read(file, options); // Empty result is not an exception — the file was read but contained no matching barcode if (results == null || results.Count == 0) { emptyCount++; errors.Add((file, "No barcodes detected")); // record so caller can adjust options continue; } foreach (BarcodeResult result in results) {Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}"); } successCount++; } catch (IronBarCodePdfPasswordException) { // PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover failCount++; errors.Add((file, "Password-protected PDF")); } catch (IronBarCodeFileException ex) { // File is corrupted, locked, or in an unsupported image format failCount++; errors.Add((file, $"File error: {ex.Message}")); } catch (FileNotFoundException ex) { // File was in the directory listing but deleted before the read completed (race condition) failCount++; errors.Add((file, $"File not found: {ex.Message}")); } catch (IronBarCodeException ex) { // Catch-all for any other IronBarcode-specific errors not handled above failCount++; errors.Add((file, $"{ex.GetType().Name}: {ex.Message}")); } catch (Exception ex) { // Unexpected non-IronBarcode error — log the full type for investigation failCount++; errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}")); }}sw.Stop();// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit codeConsole.WriteLine("\n--- Batch Summary ---");Console.WriteLine($"Total files: {files.Length}");Console.WriteLine($"Success: {successCount}");Console.WriteLine($"Empty reads: {emptyCount}");Console.WriteLine($"Failures: {failCount}");Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");if (errors.Any()){Console.WriteLine("\n--- Error Details ---"); foreach (var (errorFile, errorMsg) in errors) {Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}"); }}
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;
// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";
// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced, // balances throughput vs accuracy
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
ExpectMultipleBarcodes = true // scan each file fully
};
// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();
foreach (string file in files)
{
try
{
BarcodeResults results = BarcodeReader.Read(file, options);
// Empty result is not an exception — the file was read but contained no matching barcode
if (results == null || results.Count == 0)
{
emptyCount++;
errors.Add((file, "No barcodes detected")); // record so caller can adjust options
continue;
}
foreach (BarcodeResult result in results)
{
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
}
successCount++;
}
catch (IronBarCodePdfPasswordException)
{
// PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount++;
errors.Add((file, "Password-protected PDF"));
}
catch (IronBarCodeFileException ex)
{
// File is corrupted, locked, or in an unsupported image format
failCount++;
errors.Add((file, $"File error: {ex.Message}"));
}
catch (FileNotFoundException ex)
{
// File was in the directory listing but deleted before the read completed (race condition)
failCount++;
errors.Add((file, $"File not found: {ex.Message}"));
}
catch (IronBarCodeException ex)
{
// Catch-all for any other IronBarcode-specific errors not handled above
failCount++;
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
}
catch (Exception ex)
{
// Unexpected non-IronBarcode error — log the full type for investigation
failCount++;
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
}
}
sw.Stop();
// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files: {files.Length}");
Console.WriteLine($"Success: {successCount}");
Console.WriteLine($"Empty reads: {emptyCount}");
Console.WriteLine($"Failures: {failCount}");
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");
if (errors.Any())
{
Console.WriteLine("\n--- Error Details ---");
foreach (var (errorFile, errorMsg) in errors)
{
Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}");
}
}
ImportsIronBarCodeImportsIronBarCode.ExceptionsImportsSystem.Diagnostics' Enable built-in logging for the entire batch run so internal processing steps' are captured in the log file alongside the per-file console outputIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.AllIronSoftware.Logger.LogFilePath = "batch-run.log"' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectoriesDim files AsString() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)Dim options As New BarcodeReaderOptionsWith { .Speed = ReadingSpeed.Balanced, ' balances throughput vs accuracy .ExpectBarcodeTypes = BarcodeEncoding.Code128OrBarcodeEncoding.QRCode, ' limit to known formats .ExpectMultipleBarcodes = True ' scan each file fully}' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)Dim successCount AsInteger = 0Dim failCount AsInteger = 0Dim emptyCount AsInteger = 0Dim errors As New List(Of (FileAsString, ErrorAsString))() ' per-file error context for root cause analysisDim sw AsStopwatch = Stopwatch.StartNew()For Each file AsStringIn filesTry Dim results AsBarcodeResults = BarcodeReader.Read(file, options) ' Empty result is not an exception — the file was read but contained no matching barcode If results Is NothingOrElse results.Count = 0 Then emptyCount += 1 errors.Add((file, "No barcodes detected")) ' record so caller can adjust options Continue For End If For Each result AsBarcodeResultIn resultsConsole.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}") Next successCount += 1Catch ex AsIronBarCodePdfPasswordException ' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover failCount += 1 errors.Add((file, "Password-protected PDF"))Catch ex AsIronBarCodeFileException ' File is corrupted, locked, or in an unsupported image format failCount += 1 errors.Add((file, $"File error: {ex.Message}"))Catch ex AsFileNotFoundException ' File was in the directory listing but deleted before the read completed (race condition) failCount += 1 errors.Add((file, $"File not found: {ex.Message}"))Catch ex AsIronBarCodeException ' Catch-all for any other IronBarcode-specific errors not handled above failCount += 1 errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))Catch ex AsException ' Unexpected non-IronBarcode error — log the full type for investigation failCount += 1 errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))EndTryNextsw.Stop()' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit codeConsole.WriteLine(vbCrLf & "--- Batch Summary ---")Console.WriteLine($"Total files: {files.Length}")Console.WriteLine($"Success: {successCount}")Console.WriteLine($"Empty reads: {emptyCount}")Console.WriteLine($"Failures: {failCount}")Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s")If errors.Any() ThenConsole.WriteLine(vbCrLf & "--- Error Details ---") For Each errorDetail In errorsConsole.Error.WriteLine($" {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}") NextEnd If
Imports IronBarCode
Imports IronBarCode.Exceptions
Imports System.Diagnostics
' Enable built-in logging for the entire batch run so internal processing steps
' are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "batch-run.log"
' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
Dim files As String() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced, ' balances throughput vs accuracy
.ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit to known formats
.ExpectMultipleBarcodes = True ' scan each file fully
}
' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
Dim successCount As Integer = 0
Dim failCount As Integer = 0
Dim emptyCount As Integer = 0
Dim errors As New List(Of (File As String, Error As String))() ' per-file error context for root cause analysis
Dim sw As Stopwatch = Stopwatch.StartNew()
For Each file As String In files
Try
Dim results As BarcodeResults = BarcodeReader.Read(file, options)
' Empty result is not an exception — the file was read but contained no matching barcode
If results Is Nothing OrElse results.Count = 0 Then
emptyCount += 1
errors.Add((file, "No barcodes detected")) ' record so caller can adjust options
Continue For
End If
For Each result As BarcodeResult In results
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}")
Next
successCount += 1
Catch ex As IronBarCodePdfPasswordException
' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount += 1
errors.Add((file, "Password-protected PDF"))
Catch ex As IronBarCodeFileException
' File is corrupted, locked, or in an unsupported image format
failCount += 1
errors.Add((file, $"File error: {ex.Message}"))
Catch ex As FileNotFoundException
' File was in the directory listing but deleted before the read completed (race condition)
failCount += 1
errors.Add((file, $"File not found: {ex.Message}"))
Catch ex As IronBarCodeException
' Catch-all for any other IronBarcode-specific errors not handled above
failCount += 1
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))
Catch ex As Exception
' Unexpected non-IronBarcode error — log the full type for investigation
failCount += 1
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))
End Try
Next
sw.Stop()
' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine(vbCrLf & "--- Batch Summary ---")
Console.WriteLine($"Total files: {files.Length}")
Console.WriteLine($"Success: {successCount}")
Console.WriteLine($"Empty reads: {emptyCount}")
Console.WriteLine($"Failures: {failCount}")
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s")
If errors.Any() Then
Console.WriteLine(vbCrLf & "--- Error Details ---")
For Each errorDetail In errors
Console.Error.WriteLine($" {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}")
Next
End If
Resultado
Durante la ejecución, la consola muestra una línea por cada BarCode descodificado, seguida de un resumen con el recuento de archivos, los éxitos, las lecturas vacías, los fallos y el tiempo transcurrido. Los errores se enumeran con sus correspondientes nombres de archivo y los motivos del fallo.
El proceso distingue tres categorías de resultados: éxito (BarCodes encontrados y descodificados), vacío (archivo leído pero sin BarCodes detectados) y fallo (excepción lanzada). Esta distinción es importante porque las lecturas vacías y los errores requieren respuestas diferentes. Las lecturas vacías pueden requerir ajustes de formato más amplios, mientras que los errores suelen indicar problemas de infraestructura, como archivos que faltan, recursos bloqueados o dependencias nativas que faltan.
La lista de errores mantiene el contexto de cada archivo para facilitar el análisis de la causa raíz. En un pipeline de CI/CD, analice esta salida para establecer códigos de salida (cero para éxito completo y no cero cuando failCount es mayor que cero) o reenvíe detalles de error a un sistema de alertas.
Para un mayor rendimiento, habilite el procesamiento en paralelo configurando Multithreaded a true y ajustando MaxParallelThreads para que coincida con los núcleos de CPU disponibles. Mantenga la aislamiento por archivo envolviendo la iteración en paralelo en Parallel.ForEach y utilizando una colección segura para hilos para la lista de errores.
Diagnóstico de errores en el pipeline fiscal español
Los sistemas de facturación electrónica española presentan patrones de error específicos que el sistema de excepciones de IronBarcode ayuda a resolver:
Errores en la generación del QR de AEAT (VeriFactu): La excepción IronBarCodeContentTooLongEncodingException indica que la URL de AEAT supera la capacidad de la versión QR configurada. La URL completa de sede.agenciatributaria.gob.es con los cinco parámetros suele requerir QR Versión 4 o superior. Solución: no limitar la versión QR manualmente y dejar que IronBarcode la seleccione automáticamente.
Errores de codificación URL: Si el parámetro nif contiene caracteres no válidos (p. ej., letras minúsculas en CIF/NIF antes del escape) o el parámetro huella no está correctamente codificado en URL, el QR generado no superará la validación del endpoint de AEAT. Use Uri.EscapeDataString() antes de construir la URL y envuelva la generación en IronBarCodeEncodingException para capturar estos fallos.
Errores de lectura de QR de TicketBAI: Cuando el lector de QR devuelve una colección vacía al procesar tíquets de Bizkaia, Gipuzkoa o Araba, verifique que ExpectBarcodeTypes incluya BarcodeEncoding.QRCode y que la calidad de la imagen sea suficiente. El bloque de diagnóstico [WARN] registra los tipos configurados y la velocidad de lectura para facilitar la depuración.
Procesamiento por lotes SII: En pipelines de reconciliación del SII con cientos de facturas por lote, el patrón de aislamiento por archivo distingue entre facturas con QR válido (éxito), facturas sin QR (lectura vacía) y facturas con imagen dañada (excepción). El informe de resumen con recuentos de éxito/fallo facilita el análisis de la causa raíz antes de la comunicación a la AEAT.
Para la trazabilidad SILICIE en entornos farmacéuticos, capture IronBarCodeFileException al procesar imágenes de etiquetas de medicamentos escaneadas que puedan estar dañadas o tener resolución insuficiente, y registre el código de producto y lote para su reescaneo.
Preguntas Frecuentes
¿Cómo puedo manejar errores en operaciones de códigos de barras usando IronBarcode?
IronBarcode proporciona excepciones tipadas y registro incorporado para gestionar y manejar eficientemente errores en operaciones de códigos de barras, asegurando que tu aplicación funcione sin problemas.
¿Qué características ofrece IronBarcode para depurar problemas de códigos de barras?
IronBarcode incluye extracción de diagnóstico y aislamiento de errores por lotes listo para producción, los cuales ayudan a los desarrolladores a identificar y resolver problemas relacionados con códigos de barras de manera eficiente.
¿Puede IronBarcode registrar errores durante el procesamiento de códigos de barras?
Sí, IronBarcode tiene capacidades de registro integrado que permiten a los desarrolladores capturar y registrar detalles de errores durante el procesamiento de códigos de barras, facilitando una depuración más fácil.
¿Qué son las excepciones tipadas en IronBarcode?
Las excepciones tipadas en IronBarcode son tipos de error específicos que proporcionan información detallada sobre los problemas de operación de códigos de barras, facilitando a los desarrolladores diagnosticar y reparar problemas.
¿Cómo asiste IronBarcode con el aislamiento de errores por lotes?
IronBarcode ofrece aislamiento de errores por lotes listo para producción, lo cual ayuda a separar operaciones de códigos de barras erróneas de las exitosas, agilizando la gestión de errores en el procesamiento por lotes.
¿Existe una manera de extraer diagnósticos de operaciones de códigos de barras usando IronBarcode?
Sí, IronBarcode proporciona herramientas de extracción de diagnóstico que ayudan a los desarrolladores a recopilar información detallada sobre las operaciones de códigos de barras, ayudando en la resolución de problemas y errores.
How can I catch and interpret exceptions effectively in IronBarcode?
Catch and interpret exceptions in IronBarcode by ordering your try-catch blocks from specific to general. Start with actionable exceptions like file errors or PDF password issues and end with the base IronBarCodeException to ensure comprehensive error handling.
What properties of BarcodeResult can be used for post-mortem analysis?
The BarcodeResult object in IronBarcode provides properties like BarcodeType, Value, PageNumber, and Points (coordinates) for post-mortem analysis. These properties help in understanding unexpected results by checking the actual versus expected barcode type and verifying the page number.
In IronBarcode, how can I prevent false positives during barcode reads?
To prevent false positives during barcode reads in IronBarcode, you can use image filters to enhance image quality and the RemoveFalsePositive option. Additionally, adjusting reading speed and ExpectBarcodeTypes can minimize errors from noisy backgrounds.
How does IronBarcode handle errors from encrypted PDFs?
IronBarcode handles errors from encrypted PDFs using the IronBarCodePdfPasswordException. To process such files, supply the password using PdfBarcodeReaderOptions or log and skip them for non-disruptive barcode processing.
Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien estructurados y visualmente atractivos.