# Cómo gestionar los mensajes de error de códigos QR en C#
La gestión de errores de IronQR te ayuda a detectar fallos de lectura y escritura, registrar diagnósticos y obtener resultados claros en cada escaneo. En España, un error silencioso en la generación del QR de AEAT puede traducirse en una factura no conforme con VERI*FACTU (Real Decreto 1007/2023) o en un ticket TicketBAI rechazado por las haciendas forales de Bizkaia, Gipuzkoa y Araba. Si no se añaden comprobaciones explícitas, tanto un resultado vacío como un archivo dañado no devolverán nada, por lo que no sabrás qué ha fallado. Al añadir un manejo de excepciones específico y un registro de diagnóstico, puede convertir los fallos silenciosos en información útil. Esta guía explica cómo gestionar los resultados vacíos, gestionar las excepciones en tiempo de escritura y crear un envoltorio de registro estructurado para el procesamiento por lotes.
*as-heading:2(Guía de inicio rápido: Gestionar errores de códigos QR)*
Envuelva las operaciones de lectura de QR en un bloque `try-catch` y registre diagnósticos para fallos de archivo y decodificación.
```csharp
:title=Quickstart
using IronQr;
using IronSoftware.Drawing;
try
{
var input = new QrImageInput(AnyBitmap.FromFile("label.png"));
var results = new QrReader().Read(input);
Console.WriteLine($"Found {results.Count()} QR code(s)");
}
catch (IOException ex)
{
Console.Error.WriteLine($"File error: {ex.Message}");
}
```
<div class="hsg-featured-snippet">
<h3>Flujo de trabajo mínimo (5 pasos)</h3>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://nuget.org/packages/IronQR/">Descarga la biblioteca IronQR C# para la gestión de errores de códigos QR</a></li>
<li>Envuelva las llamadas de lectura/escritura de QR en bloques <code>try-catch</code></li>
<li>Captura <code>IOException</code> y <code>ArgumentException</code> para errores específicos</li>
<li>Registrar diagnósticos de resultados vacíos y excepciones</li>
<li>Utilice el registro JSON estructurado para la observabilidad del pipeline</li>
</ol>
</div>
## Gestión de errores de lectura y resultados vacíos
Sin registro, un resultado vacío y un archivo dañado parecen idénticos para el usuario. El siguiente ejemplo detecta errores de acceso a archivos y emite una advertencia si el análisis no devuelve ningún resultado.
### Entrada
Este ejemplo de entrada QR se encuentra en el disco. Simularemos ambos escenarios: uno en el que el usuario recupera y descodifica el archivo, y otro en el que la ruta del archivo es incorrecta.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/qr/how-to/detailed-error-messages/input-scan-one.webp"
alt="Codificación válida de entrada de códigos QR https://ironsoftware.com/qr/scan-1"
class="img-responsive add-shadow" />
</div>
</div>
```cs
using IronQr;
using IronSoftware.Drawing;
string filePath = "damaged-scan.png";
try
{
// File-level failure throws IOException or FileNotFoundException
var inputBmp = AnyBitmap.FromFile(filePath);
var imageInput = new QrImageInput(inputBmp);
var reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(imageInput);
if (!results.Any())
{
// Not an exception — but a diagnostic event worth logging
Console.Error.WriteLine($"[WARN] No QR codes found in: {filePath}");
Console.Error.WriteLine($" Action: Verify image quality or try a different scan");
}
else
{
foreach (QrResult result in results)
{
Console.WriteLine($"[{result.QrType}] {result.Value}");
}
}
}
catch (FileNotFoundException)
{
Console.Error.WriteLine($"[ERROR] File not found: {filePath}");
}
catch (IOException ex)
{
Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}");
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}");
}
```
### Resultado
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/qr/how-to/detailed-error-messages/success-output-qr.webp" alt="Salida de terminal que muestra [QR] https://ironsoftware.com/qr/scan-1 para indicar que se ha leído correctamente el código QR" class="img-responsive add-shadow" />
</div>
</div>
[[i:(Una lectura exitosa solo devolvería el valor del código QR, mientras que un error durante el tiempo de ejecución mostraría el mensaje de excepción o advertencias que se muestran a continuación.)]]
La consola a continuación muestra un `[WARN]` para el caso de resultado vacío y un `[ERROR]` para el archivo faltante, con la ruta de archivo y una acción sugerida para cada uno.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/qr/how-to/detailed-error-messages/output-read-diagnostics.webp" alt="Salida de terminal que muestra WARN por no encontrar códigos QR en damaged-scan.png y ERROR por no encontrar el archivo missing-label.png" class="img-responsive add-shadow" />
</div>
</div>
---
## Gestión de errores de escritura
Pasar `null` a `QrWriter.Write` activa un `IronQrEncodingException`. Los datos que superen la capacidad del [nivel de corrección de errores](https://ironsoftware.com/csharp/qr/how-to/error-correction-qr-code/) configurado también se descartan, ya que los niveles de corrección más altos reducen la capacidad de datos disponible.
### Entrada
Las dos variables de entrada a continuación definen los escenarios de fallo: `nullContent` es `null` y `oversizedContent` es una cadena de 5,000 caracteres que excede la capacidad del QR en el nivel de corrección más alto.
```cs
using IronQr;
string? content = null; // null throws IronQrEncodingException
string oversizedContent = new string('A', 5000); // 5,000 chars exceeds QR capacity at Highest error correction level
// Scenario 1: null input
try
{
QrCode qr = QrWriter.Write(content); // Input
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}"); // Output
}
// Scenario 2: data exceeds QR capacity at the configured error correction level
try
{
var options = new QrOptions(QrErrorCorrectionLevel.Highest);
QrCode qr = QrWriter.Write(oversizedContent, options); // Input
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}"); // Output
Console.Error.WriteLine($" Input length: {oversizedContent.Length} chars");
Console.Error.WriteLine($" Action: Reduce content or lower error correction level");
}
```
### Resultado
La consola muestra el tipo de excepción y el mensaje para ambos casos de fallo.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/qr/how-to/detailed-error-messages/output-write-diagnostics.webp" alt="Salida de terminal que muestra IronQrEncodingException por contenido nulo pasado a QrWriter.Write" class="img-responsive add-shadow" />
</div>
</div>
Registre la longitud de la entrada junto con el mensaje de excepción para determinar si el problema requiere un contenido más breve o un nivel de corrección más bajo. En cuanto a las entradas del usuario, valide la longitud de las cadenas y compruebe si hay valores nulos antes de la codificación para reducir la sobrecarga de excepciones y mejorar el diagnóstico.
---
## Registro de operaciones de códigos QR
Utilice `IronSoftware.Logger` para capturar diagnósticos internos. Para cada operación de lectura, implemente un ayudante que registre la ruta del archivo, el recuento de resultados y el tiempo transcurrido en formato JSON para garantizar una salida clara de todo el lote.
### Entrada
El lote incluye cuatro imágenes de códigos QR válidas de `qr-scans/` y un quinto archivo, `scan-05-broken.png`, con bytes no válidos.
<div class="competitors-section__wrapper-even-1">
<div class="competitors__card" style="width: 22.5%;">
<img src="/static-assets/qr/how-to/detailed-error-messages/input-scan-one.webp"
alt="Código QR que codifica https://ironsoftware.com/qr/scan-1"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
Escaneo 1
</p>
</div>
<div class="competitors__card" style="width: 22.5%;">
<img src="/static-assets/qr/how-to/detailed-error-messages/input-scan-two.webp"
alt="Código QR que codifica https://ironsoftware.com/qr/scan-2"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
Escanear 2
</p>
</div>
<div class="competitors__card" style="width: 22.5%;">
<img src="/static-assets/qr/how-to/detailed-error-messages/input-scan-three.webp"
alt="Código QR que codifica https://ironsoftware.com/qr/scan-3"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
Escaneo 3
</p>
</div>
<div class="competitors__card" style="width: 22.5%;">
<img src="/static-assets/qr/how-to/detailed-error-messages/input-scan-four.webp"
alt="Código QR que codifica https://ironsoftware.com/qr/scan-4"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
Escanear 4
</p>
</div>
</div>
```cs
using IronQr;
using IronSoftware.Drawing;
using System.Diagnostics;
// Enable shared Iron Software logging for internal diagnostics
IronQr.Logging.Logger.LoggingMode = IronQr.Logging.Logger.LoggingModes.All;
IronQr.Logging.Logger.LogFilePath = "ironqr-debug.log";
// Reusable wrapper for structured observability
(IEnumerable<QrResult> Results, bool Success, string Error) ReadQrWithDiagnostics(string filePath)
{
var sw = Stopwatch.StartNew();
try
{
var input = new QrImageInput(AnyBitmap.FromFile(filePath));
var results = new QrReader().Read(input).ToList();
sw.Stop();
Console.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
+ $"\"status\":\"ok\",\"count\":{results.Count},\"ms\":{sw.ElapsedMilliseconds}}}");
return (results, true, null);
}
catch (Exception ex)
{
sw.Stop();
string error = $"{ex.GetType().Name}: {ex.Message}";
Console.Error.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
+ $"\"status\":\"error\",\"exception\":\"{ex.GetType().Name}\","
+ $"\"message\":\"{ex.Message}\",\"ms\":{sw.ElapsedMilliseconds}}}");
return (Enumerable.Empty<QrResult>(), false, error);
}
}
// Usage: process a batch with per-file isolation
string[] files = Directory.GetFiles("qr-scans/", "*.png");
int ok = 0, fail = 0;
foreach (string file in files)
{
var (results, success, error) = ReadQrWithDiagnostics(file);
if (success && results.Any()) ok++;
else fail++;
}
Console.WriteLine($"\nBatch complete: {ok} success, {fail} failed/empty out of {files.Length} files");
```
### Resultado
La consola muestra líneas de registro JSON para cada archivo: cuatro lecturas correctas y una entrada de error estructurada para el archivo dañado, seguidas del resumen del lote. `IronSoftware.Logger` escribe diagnósticos internos en `IronQR-debug.log` al mismo tiempo. Puede descargar el registro de depuración completo [aquí](/static-assets/qr/how-to/detailed-error-messages/ironqr-debug.log).
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/qr/how-to/detailed-error-messages/output-logging-wrapper.webp" alt="Salida de terminal que muestra líneas de registro estructuradas en JSON para 4 lecturas correctas y 1 error, además de un resumen de finalización del lote" class="img-responsive add-shadow" />
</div>
</div>
La salida JSON se alimenta directamente en herramientas de agregación de registros: canalice `stdout` a Fluentd, Datadog o CloudWatch en un despliegue en contenedores. El campo `ms` muestra regresiones de latencia, y el registro de depuración captura pasos de procesamiento internos que el envoltorio no captura.
---
## Más información
- [Niveles de corrección de errores](https://ironsoftware.com/csharp/qr/how-to/error-correction-qr-code/): ajusta la resistencia del QR a nivel de codificación.
- [Guía práctica para leer códigos QR](https://ironsoftware.com/csharp/qr/how-to/read-qr-codes-from-image/): tutorial paso a paso de la lectura.
- [Tutorial del generador de códigos QR](https://ironsoftware.com/csharp/qr/tutorials/csharp-qr-code-generator/): generación con estilos y logotipos.
- [Referencia de la API de QrReader](https://ironsoftware.com/csharp/qr/object-reference/api/IronQr.QrReader.html): firmas de métodos y comentarios.
- [Referencia API de QrWriter](https://ironsoftware.com/csharp/qr/object-reference/api/IronQr.QrWriter.html): todas las sobrecargas de `Write`.
[Consulte las opciones de licencia](https://ironsoftware.com/csharp/qr/licensing/) cuando esté listo para la producción.
[Haga clic aquí para descargar ](/static-assets/qr/how-to/detailed-error-messages/DetailedErrorMessagesTest.zip) el proyecto completo de la aplicación de consola DetailedErrorMessagesTest.
## Aplicaciones regulatorias en España
En el mercado español, los errores en la codificación de códigos QR tienen consecuencias directas sobre el cumplimiento fiscal y regulatorio. Una gestión de errores robusta con IronQR no es una práctica opcional: es la diferencia entre una factura válida ante la AEAT y una infracción tributaria.
**Errores en QR de AEAT / VERI*FACTU.** El reglamento VERI*FACTU (Real Decreto 1007/2023) especifica con precisión el formato de la URL de verificación que debe codificar cada código QR de factura: `https://sede.agenciatributaria.gob.es/Sede/facturae/verificar?nif={nif}&numserie={serie}&fecha={fecha}&importe={total}`. Un error de codificación - longitud de datos excesiva, carácter no válido en el NIF, o formato de fecha incorrecto - produce un QR inescaneble que la AEAT rechazará durante la verificación. Capturar `IronQrEncodingException` y registrar la longitud del payload junto con el mensaje de error permite al equipo de desarrollo diagnosticar y corregir estos problemas antes de que lleguen a producción.
**Errores en QR TicketBAI.** Las especificaciones técnicas de las haciendas forales de Bizkaia, Gipuzkoa y Araba establecen requisitos estrictos sobre el contenido del QR TicketBAI: el `código TicketBAI`, el `NIF proveedor`, el `importe total` y la `fecha emisión` deben codificarse en un formato exacto. Un resultado vacío de `QrReader.Read` sobre un ticket impreso puede indicar un QR mal generado por el software del proveedor o un problema de contraste en la impresión. El patrón `[WARN]` / `[ERROR]` descrito en esta guía es la base de un sistema de alertas de calidad en los TPV vascos.
**Validación de DataMatrix SEVeM y SILICIE.** La AEMPS exige que el DataMatrix de cada medicamento codifique correctamente los campos de trazabilidad (GTIN, número de lote, fecha de caducidad, número de serie). Un `ArgumentNullException` por contenido nulo o un `ArgumentException` por exceso de capacidad son señales de un defecto en el pipeline de generación de etiquetas. Del mismo modo, la AEAT gestiona el sistema SILICIE para el control de contadores de alcohol, donde un DataMatrix mal codificado puede invalidar un movimiento de mercancía ante la administración.
### Ejemplo práctico: diagnóstico de un error de QR AEAT en un sistema VeriFactu
Imagine un sistema de facturación electrónica que debe generar el QR de AEAT para cada factura emitida bajo VERI*FACTU. Durante las pruebas de integración, el equipo detecta que un lote de 200 facturas produce resultados vacíos al escanear los QR generados. El flujo de diagnóstico con IronQR es el siguiente:
1. Se habilita `IronSoftware.Logger` con `LoggingMode = All` para capturar el detalle interno de cada operación.
2. El envoltorio de registro estructurado registra, para cada factura, la URL codificada, la longitud del payload y el tiempo de codificación.
3. El análisis del log revela que las facturas con `importe total` superior a 9.999,99 € producen un payload de 156 caracteres, superando la capacidad del nivel de corrección H configurado.
4. La solución: reducir el nivel de corrección a M (`ErrorCorrectionLevel.Medium`) para payloads de más de 130 caracteres, o truncar el importe a dos decimales antes de la codificación.
5. Tras el fix, el procesamiento por lotes de 200 facturas produce cuatro lecturas correctas y un único `[ERROR]` estructurado - la factura con NIF malformado - que el sistema de alertas escala automáticamente al equipo de soporte.
Este patrón garantiza que ninguna factura VeriFactu llegue al cliente con un QR inválido, evitando sanciones por incumplimiento del Real Decreto 1007/2023.
<a href="https://ironsoftware.com/csharp/qr/how-to/detailed-error-messages/" class="code_content__related-link__doc-cta-link">Diagnostique y corrija errores de QR en sistemas VeriFactu, TicketBAI y SEVeM con IronQR en C#.</a>
La gestión de errores de IronQR te ayuda a detectar fallos de lectura y escritura, registrar diagnósticos y obtener resultados claros en cada escaneo. En España, un error silencioso en la generación del QR de AEAT puede traducirse en una factura no conforme con VERI*FACTU (Real Decreto 1007/2023) o en un ticket TicketBAI rechazado por las haciendas forales de Bizkaia, Gipuzkoa y Araba. Si no se añaden comprobaciones explícitas, tanto un resultado vacío como un archivo dañado no devolverán nada, por lo que no sabrás qué ha fallado. Al añadir un manejo de excepciones específico y un registro de diagnóstico, puede convertir los fallos silenciosos en información útil. Esta guía explica cómo gestionar los resultados vacíos, gestionar las excepciones en tiempo de escritura y crear un envoltorio de registro estructurado para el procesamiento por lotes.
Guía de inicio rápido: Gestionar errores de códigos QR
Envuelva las operaciones de lectura de QR en un bloque try-catch y registre diagnósticos para fallos de archivo y decodificación.
1Install IronQR with NuGet Package Manager
PM > Install-Package IronQR
Install-Package IronQR
2Copie y ejecute este fragmento de código.
using IronQr;using IronSoftware.Drawing;try{ var input = new QrImageInput(AnyBitmap.FromFile("label.png")); var results = new QrReader().Read(input);Console.WriteLine($"Found {results.Count()} QR code(s)");}catch (IOException ex){Console.Error.WriteLine($"File error: {ex.Message}");}
using IronQr;
using IronSoftware.Drawing;
try
{
var input = new QrImageInput(AnyBitmap.FromFile("label.png"));
var results = new QrReader().Read(input);
Console.WriteLine($"Found {results.Count()} QR code(s)");
}
catch (IOException ex)
{
Console.Error.WriteLine($"File error: {ex.Message}");
}
C#
3Despliegue para probar en su entorno real
Comienza a usar IronQR en tu proyecto hoy mismo con una prueba gratuita
Envuelva las llamadas de lectura/escritura de QR en bloques try-catch
Captura IOException y ArgumentException para errores específicos
Registrar diagnósticos de resultados vacíos y excepciones
Utilice el registro JSON estructurado para la observabilidad del pipeline
Gestión de errores de lectura y resultados vacíos
Sin registro, un resultado vacío y un archivo dañado parecen idénticos para el usuario. El siguiente ejemplo detecta errores de acceso a archivos y emite una advertencia si el análisis no devuelve ningún resultado.
Entrada
Este ejemplo de entrada QR se encuentra en el disco. Simularemos ambos escenarios: uno en el que el usuario recupera y descodifica el archivo, y otro en el que la ruta del archivo es incorrecta.
using IronQr;using IronSoftware.Drawing;string filePath = "damaged-scan.png";try{ // File-level failure throws IOException or FileNotFoundException var inputBmp = AnyBitmap.FromFile(filePath); var imageInput = new QrImageInput(inputBmp); var reader = new QrReader(); IEnumerable<QrResult> results = reader.Read(imageInput); if (!results.Any()) { // Not an exception — but a diagnostic event worth loggingConsole.Error.WriteLine($"[WARN] No QR codes found in: {filePath}");Console.Error.WriteLine($" Action: Verify image quality or try a different scan"); } else { foreach (QrResult result in results) {Console.WriteLine($"[{result.QrType}] {result.Value}"); } }}catch (FileNotFoundException){Console.Error.WriteLine($"[ERROR] File not found: {filePath}");}catch (IOException ex){Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}");}catch (Exception ex){Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}");}
using IronQr;
using IronSoftware.Drawing;
string filePath = "damaged-scan.png";
try
{
// File-level failure throws IOException or FileNotFoundException
var inputBmp = AnyBitmap.FromFile(filePath);
var imageInput = new QrImageInput(inputBmp);
var reader = new QrReader();
IEnumerable<QrResult> results = reader.Read(imageInput);
if (!results.Any())
{
// Not an exception — but a diagnostic event worth logging
Console.Error.WriteLine($"[WARN] No QR codes found in: {filePath}");
Console.Error.WriteLine($" Action: Verify image quality or try a different scan");
}
else
{
foreach (QrResult result in results)
{
Console.WriteLine($"[{result.QrType}] {result.Value}");
}
}
}
catch (FileNotFoundException)
{
Console.Error.WriteLine($"[ERROR] File not found: {filePath}");
}
catch (IOException ex)
{
Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}");
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}");
}
ImportsIronQrImportsIronSoftware.DrawingModuleModule1 Sub Main() Dim filePath AsString = "damaged-scan.png"Try ' File-level failure throws IOException or FileNotFoundException Dim inputBmp = AnyBitmap.FromFile(filePath) Dim imageInput = New QrImageInput(inputBmp) Dim reader = New QrReader() Dim results AsIEnumerable(OfQrResult) = reader.Read(imageInput) IfNot results.Any() Then ' Not an exception — but a diagnostic event worth loggingConsole.Error.WriteLine($"[WARN] No QR codes found in: {filePath}")Console.Error.WriteLine(" Action: Verify image quality or try a different scan") Else For Each result AsQrResultIn resultsConsole.WriteLine($"[{result.QrType}] {result.Value}") Next End IfCatch ex AsFileNotFoundExceptionConsole.Error.WriteLine($"[ERROR] File not found: {filePath}")Catch ex AsIOExceptionConsole.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}")Catch ex AsExceptionConsole.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}")EndTry End SubEndModule
Imports IronQr
Imports IronSoftware.Drawing
Module Module1
Sub Main()
Dim filePath As String = "damaged-scan.png"
Try
' File-level failure throws IOException or FileNotFoundException
Dim inputBmp = AnyBitmap.FromFile(filePath)
Dim imageInput = New QrImageInput(inputBmp)
Dim reader = New QrReader()
Dim results As IEnumerable(Of QrResult) = reader.Read(imageInput)
If Not results.Any() Then
' Not an exception — but a diagnostic event worth logging
Console.Error.WriteLine($"[WARN] No QR codes found in: {filePath}")
Console.Error.WriteLine(" Action: Verify image quality or try a different scan")
Else
For Each result As QrResult In results
Console.WriteLine($"[{result.QrType}] {result.Value}")
Next
End If
Catch ex As FileNotFoundException
Console.Error.WriteLine($"[ERROR] File not found: {filePath}")
Catch ex As IOException
Console.Error.WriteLine($"[ERROR] Cannot read file: {filePath} — {ex.Message}")
Catch ex As Exception
Console.Error.WriteLine($"[ERROR] Unexpected failure reading {filePath}: {ex.GetType().Name} — {ex.Message}")
End Try
End Sub
End Module
Resultado
Por favor nota: Una lectura exitosa solo devolvería el valor del código QR, mientras que un error durante el tiempo de ejecución mostraría el mensaje de excepción o advertencias que se muestran a continuación.
La consola a continuación muestra un [WARN] para el caso de resultado vacío y un [ERROR] para el archivo faltante, con la ruta de archivo y una acción sugerida para cada uno.
Gestión de errores de escritura
Pasar null a QrWriter.Write activa un IronQrEncodingException. Los datos que superen la capacidad del nivel de corrección de errores configurado también se descartan, ya que los niveles de corrección más altos reducen la capacidad de datos disponible.
Entrada
Las dos variables de entrada a continuación definen los escenarios de fallo: nullContent es null y oversizedContent es una cadena de 5,000 caracteres que excede la capacidad del QR en el nivel de corrección más alto.
using IronQr;string? content = null; // null throws IronQrEncodingException string oversizedContent = new string('A', 5000); // 5,000 chars exceeds QR capacity at Highest error correction level // Scenario 1: null inputtry{ QrCode qr = QrWriter.Write(content); // Input}catch (Exception ex){Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}"); // Output}// Scenario 2: data exceeds QR capacity at the configured error correction leveltry{ var options = new QrOptions(QrErrorCorrectionLevel.Highest); QrCode qr = QrWriter.Write(oversizedContent, options); // Input}catch (Exception ex){Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}"); // OutputConsole.Error.WriteLine($" Input length: {oversizedContent.Length} chars");Console.Error.WriteLine($" Action: Reduce content or lower error correction level");}
using IronQr;
string? content = null; // null throws IronQrEncodingException
string oversizedContent = new string('A', 5000); // 5,000 chars exceeds QR capacity at Highest error correction level
// Scenario 1: null input
try
{
QrCode qr = QrWriter.Write(content); // Input
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}"); // Output
}
// Scenario 2: data exceeds QR capacity at the configured error correction level
try
{
var options = new QrOptions(QrErrorCorrectionLevel.Highest);
QrCode qr = QrWriter.Write(oversizedContent, options); // Input
}
catch (Exception ex)
{
Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}"); // Output
Console.Error.WriteLine($" Input length: {oversizedContent.Length} chars");
Console.Error.WriteLine($" Action: Reduce content or lower error correction level");
}
ImportsIronQrDim content AsString = Nothing ' Nothing throws IronQrEncodingException Dim oversizedContent AsString = New String("A"c, 5000) ' 5,000 chars exceeds QR capacity at Highest error correction level ' Scenario 1: null inputTry Dim qr AsQrCode = QrWriter.Write(content) ' InputCatch ex AsExceptionConsole.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}") ' OutputEndTry' Scenario 2: data exceeds QR capacity at the configured error correction levelTry Dim options As New QrOptions(QrErrorCorrectionLevel.Highest) Dim qr AsQrCode = QrWriter.Write(oversizedContent, options) ' InputCatch ex AsExceptionConsole.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}") ' OutputConsole.Error.WriteLine($" Input length: {oversizedContent.Length} chars")Console.Error.WriteLine(" Action: Reduce content or lower error correction level")EndTry
Imports IronQr
Dim content As String = Nothing ' Nothing throws IronQrEncodingException
Dim oversizedContent As String = New String("A"c, 5000) ' 5,000 chars exceeds QR capacity at Highest error correction level
' Scenario 1: null input
Try
Dim qr As QrCode = QrWriter.Write(content) ' Input
Catch ex As Exception
Console.Error.WriteLine($"[ERROR] Null content: {ex.GetType().Name} — {ex.Message}") ' Output
End Try
' Scenario 2: data exceeds QR capacity at the configured error correction level
Try
Dim options As New QrOptions(QrErrorCorrectionLevel.Highest)
Dim qr As QrCode = QrWriter.Write(oversizedContent, options) ' Input
Catch ex As Exception
Console.Error.WriteLine($"[ERROR] QR capacity exceeded: {ex.Message}") ' Output
Console.Error.WriteLine($" Input length: {oversizedContent.Length} chars")
Console.Error.WriteLine(" Action: Reduce content or lower error correction level")
End Try
Resultado
La consola muestra el tipo de excepción y el mensaje para ambos casos de fallo.
Registre la longitud de la entrada junto con el mensaje de excepción para determinar si el problema requiere un contenido más breve o un nivel de corrección más bajo. En cuanto a las entradas del usuario, valide la longitud de las cadenas y compruebe si hay valores nulos antes de la codificación para reducir la sobrecarga de excepciones y mejorar el diagnóstico.
Registro de operaciones de códigos QR
Utilice IronSoftware.Logger para capturar diagnósticos internos. Para cada operación de lectura, implemente un ayudante que registre la ruta del archivo, el recuento de resultados y el tiempo transcurrido en formato JSON para garantizar una salida clara de todo el lote.
Entrada
El lote incluye cuatro imágenes de códigos QR válidas de qr-scans/ y un quinto archivo, scan-05-broken.png, con bytes no válidos.
Escaneo 1
Escanear 2
Escaneo 3
Escanear 4
using IronQr;using IronSoftware.Drawing;using System.Diagnostics;// Enable shared Iron Software logging for internal diagnosticsIronQr.Logging.Logger.LoggingMode = IronQr.Logging.Logger.LoggingModes.All;IronQr.Logging.Logger.LogFilePath = "ironqr-debug.log";// Reusable wrapper for structured observability(IEnumerable<QrResult> Results, boolSuccess, stringError) ReadQrWithDiagnostics(string filePath){ var sw = Stopwatch.StartNew(); try { var input = new QrImageInput(AnyBitmap.FromFile(filePath)); var results = new QrReader().Read(input).ToList(); sw.Stop();Console.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\"," + $"\"status\":\"ok\",\"count\":{results.Count},\"ms\":{sw.ElapsedMilliseconds}}}"); return (results, true, null); } catch (Exception ex) { sw.Stop(); string error = $"{ex.GetType().Name}: {ex.Message}";Console.Error.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\"," + $"\"status\":\"error\",\"exception\":\"{ex.GetType().Name}\"," + $"\"message\":\"{ex.Message}\",\"ms\":{sw.ElapsedMilliseconds}}}"); return (Enumerable.Empty<QrResult>(), false, error); }}// Usage: process a batch with per-file isolationstring[] files = Directory.GetFiles("qr-scans/", "*.png");int ok = 0, fail = 0;foreach (string file in files){ var (results, success, error) = ReadQrWithDiagnostics(file); if (success && results.Any()) ok++; else fail++;}Console.WriteLine($"\nBatch complete: {ok} success, {fail} failed/empty out of {files.Length} files");
using IronQr;
using IronSoftware.Drawing;
using System.Diagnostics;
// Enable shared Iron Software logging for internal diagnostics
IronQr.Logging.Logger.LoggingMode = IronQr.Logging.Logger.LoggingModes.All;
IronQr.Logging.Logger.LogFilePath = "ironqr-debug.log";
// Reusable wrapper for structured observability
(IEnumerable<QrResult> Results, bool Success, string Error) ReadQrWithDiagnostics(string filePath)
{
var sw = Stopwatch.StartNew();
try
{
var input = new QrImageInput(AnyBitmap.FromFile(filePath));
var results = new QrReader().Read(input).ToList();
sw.Stop();
Console.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
+ $"\"status\":\"ok\",\"count\":{results.Count},\"ms\":{sw.ElapsedMilliseconds}}}");
return (results, true, null);
}
catch (Exception ex)
{
sw.Stop();
string error = $"{ex.GetType().Name}: {ex.Message}";
Console.Error.WriteLine($"{{\"op\":\"qr_read\",\"file\":\"{Path.GetFileName(filePath)}\","
+ $"\"status\":\"error\",\"exception\":\"{ex.GetType().Name}\","
+ $"\"message\":\"{ex.Message}\",\"ms\":{sw.ElapsedMilliseconds}}}");
return (Enumerable.Empty<QrResult>(), false, error);
}
}
// Usage: process a batch with per-file isolation
string[] files = Directory.GetFiles("qr-scans/", "*.png");
int ok = 0, fail = 0;
foreach (string file in files)
{
var (results, success, error) = ReadQrWithDiagnostics(file);
if (success && results.Any()) ok++;
else fail++;
}
Console.WriteLine($"\nBatch complete: {ok} success, {fail} failed/empty out of {files.Length} files");
C#
Resultado
La consola muestra líneas de registro JSON para cada archivo: cuatro lecturas correctas y una entrada de error estructurada para el archivo dañado, seguidas del resumen del lote. IronSoftware.Logger escribe diagnósticos internos en IronQR-debug.log al mismo tiempo. Puede descargar el registro de depuración completo aquí.
La salida JSON se alimenta directamente en herramientas de agregación de registros: canalice stdout a Fluentd, Datadog o CloudWatch en un despliegue en contenedores. El campo ms muestra regresiones de latencia, y el registro de depuración captura pasos de procesamiento internos que el envoltorio no captura.
En el mercado español, los errores en la codificación de códigos QR tienen consecuencias directas sobre el cumplimiento fiscal y regulatorio. Una gestión de errores robusta con IronQR no es una práctica opcional: es la diferencia entre una factura válida ante la AEAT y una infracción tributaria.
Errores en QR de AEAT / VERI*FACTU. El reglamento VERI*FACTU (Real Decreto 1007/2023) especifica con precisión el formato de la URL de verificación que debe codificar cada código QR de factura: https://sede.agenciatributaria.gob.es/Sede/facturae/verificar?nif={nif}&numserie={serie}&fecha={fecha}&importe={total}. Un error de codificación - longitud de datos excesiva, carácter no válido en el NIF, o formato de fecha incorrecto - produce un QR inescaneble que la AEAT rechazará durante la verificación. Capturar IronQrEncodingException y registrar la longitud del payload junto con el mensaje de error permite al equipo de desarrollo diagnosticar y corregir estos problemas antes de que lleguen a producción.
Errores en QR TicketBAI. Las especificaciones técnicas de las haciendas forales de Bizkaia, Gipuzkoa y Araba establecen requisitos estrictos sobre el contenido del QR TicketBAI: el código TicketBAI, el NIF proveedor, el importe total y la fecha emisión deben codificarse en un formato exacto. Un resultado vacío de QrReader.Read sobre un ticket impreso puede indicar un QR mal generado por el software del proveedor o un problema de contraste en la impresión. El patrón [WARN] / [ERROR] descrito en esta guía es la base de un sistema de alertas de calidad en los TPV vascos.
Validación de DataMatrix SEVeM y SILICIE. La AEMPS exige que el DataMatrix de cada medicamento codifique correctamente los campos de trazabilidad (GTIN, número de lote, fecha de caducidad, número de serie). Un ArgumentNullException por contenido nulo o un ArgumentException por exceso de capacidad son señales de un defecto en el pipeline de generación de etiquetas. Del mismo modo, la AEAT gestiona el sistema SILICIE para el control de contadores de alcohol, donde un DataMatrix mal codificado puede invalidar un movimiento de mercancía ante la administración.
Ejemplo práctico: diagnóstico de un error de QR AEAT en un sistema VeriFactu
Imagine un sistema de facturación electrónica que debe generar el QR de AEAT para cada factura emitida bajo VERI*FACTU. Durante las pruebas de integración, el equipo detecta que un lote de 200 facturas produce resultados vacíos al escanear los QR generados. El flujo de diagnóstico con IronQR es el siguiente:
Se habilita IronSoftware.Logger con LoggingMode = All para capturar el detalle interno de cada operación.
El envoltorio de registro estructurado registra, para cada factura, la URL codificada, la longitud del payload y el tiempo de codificación.
El análisis del log revela que las facturas con importe total superior a 9.999,99 € producen un payload de 156 caracteres, superando la capacidad del nivel de corrección H configurado.
La solución: reducir el nivel de corrección a M (ErrorCorrectionLevel.Medium) para payloads de más de 130 caracteres, o truncar el importe a dos decimales antes de la codificación.
Tras el fix, el procesamiento por lotes de 200 facturas produce cuatro lecturas correctas y un único [ERROR] estructurado - la factura con NIF malformado - que el sistema de alertas escala automáticamente al equipo de soporte.
Este patrón garantiza que ninguna factura VeriFactu llegue al cliente con un QR inválido, evitando sanciones por incumplimiento del Real Decreto 1007/2023.
¿Cómo puedo depurar operaciones de lectura/escritura de códigos QR en C#?
Puede depurar operaciones de lectura/escritura de códigos QR en C# usando IronQR capturando excepciones, registrando diagnósticos y monitoreando el procesamiento por lotes con salida estructurada.
¿Qué debo hacer si encuentro un error al procesar códigos QR en C#?
Si encuentra un error al procesar códigos QR en C#, use IronQR para capturar y manejar excepciones. Esto le permitirá identificar y resolver problemas eficazmente.
¿Cómo ayuda IronQR a monitorear el procesamiento por lotes de códigos QR?
IronQR ayuda a monitorear el procesamiento por lotes de códigos QR proporcionando salida estructurada, lo cual ayuda a identificar y solucionar cualquier error o ineficiencia durante el proceso.
¿Puede IronQR registrar diagnósticos para operaciones de códigos QR?
Sí, IronQR puede registrar diagnósticos para operaciones de códigos QR, permitiéndole rastrear y analizar el rendimiento y errores en sus aplicaciones C#.
¿Cuáles son las excepciones comunes en el procesamiento de códigos QR con IronQR?
Las excepciones comunes en el procesamiento de códigos QR con IronQR incluyen problemas relacionados con códigos QR ilegibles y manejo incorrecto de formatos, que pueden gestionarse mediante un manejo adecuado de excepciones en su código C#.
How can I improve error detection during QR code processing with IronQR?
Improve error detection by implementing logging that captures detailed information on file paths, operation status, result counts, and execution time. This data supports easier debugging and system observability.
Can IronQR's logging output be integrated with log aggregation tools?
Yes, the JSON output from IronQR can be fed directly into log aggregation tools such as Fluentd, Datadog, or CloudWatch, making it suitable for containerized deployments and enhancing monitoring capabilities.
What approach does IronQR suggest for handling batch QR code operations?
IronQR recommends processing each file in isolation, logging the results for each read operation to help identify errors, and providing a complete batch summary that tallies successes and failures.
How does IronQR assist in diagnosing file-level failures during QR code scans?
IronQR detects file-level failures like IOException and FileNotFoundException, providing descriptive error messages which can be logged to pinpoint issues such as incorrect file paths or unreadable files.
Why is it important to wrap QR read/write calls in try-catch blocks?
Wrapping read/write operations in try-catch blocks ensures that failures do not crash the application, allowing you to handle exceptions gracefully, log necessary diagnostics, and guide the user with useful messages.
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.