Comment gérer les erreurs et déboguer les opérations de code-barres en C

This article was translated from English: Does it need improvement?
Translated
View the article in English

Les chaînes de traitement des codes-barres peuvent échouer silencieusement, les résultats nuls étant souvent confondus avec l'absence de code-barres. Cependant, des problèmes tels que des fichiers corrompus, des PDF protégés par mot de passe ou des incompatibilités de format peuvent en être la cause. La mise en œuvre d'une journalisation appropriée et d'une gestion structurée des erreurs permet de déceler ces défaillances et de fournir des diagnostics exploitables.

IronBarcode offre une hiérarchie d'exceptions typées dans l'espace de noms IronBarcode, une API de journalisation intégrée et des propriétés BarcodeResult détaillées. Ces propriétés comprennent le format détecté, la valeur décodée, le numéro de page et les coordonnées pour chaque décodage réussi.

Ce guide explique comment intercepter et interpréter les exceptions typées, extraire le contexte de diagnostic des lectures ayant échoué, activer la journalisation structurée et isoler les échecs lors des opérations par lots.

Démarrage rapide : Gérer les erreurs de code-barres et activer les diagnostics

Enveloppez les appels de lecture/écriture dans des blocs try-catch ciblant les exceptions typées d'IronBarcode pour afficher des messages d'erreur exploitables au lieu d'échecs silencieux.

  1. Installez IronBarcode avec le Gestionnaire de Packages NuGet

    PM > Install-Package BarCode
  2. Copiez et exécutez cet extrait de code.

    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}");
    }
  3. Déployez pour tester sur votre environnement de production.

    Commencez à utiliser IronBarcode dans votre projet dès aujourd'hui avec un essai gratuit

    arrow pointer

Comment intercepter et interpréter les exceptions IronBarcode ?

Gérer les exceptions IronBarcode, des plus spécifiques aux plus générales. Ordonnez les blocs catch de traiter d'abord les exceptions exploitables, telles que les erreurs de fichier, de mot de passe PDF et d'encodage, puis le type de base. L'espace de noms IronBarCode.Exceptions définit 11 types d'exceptions, chacun correspondant à un mode de défaillance spécifique :

Types d'exception IronBarcode — Causes et corrections recommandées
Type d'exceptionDéclencheurCorrection recommandée
IronBarCodeFileExceptionLe fichier est corrompu, verrouillé ou dans un format d'image non pris en charge.Vérifiez que le fichier est dans un format image pris en charge et qu'il n'est pas verrouillé ; gérez également l' FileNotFoundException séparément pour les fichiers manquants.
IronBarCodePdfPasswordExceptionLe PDF est protégé par mot de passe ou chiffréFournissez le mot de passe via PdfBarcodeReaderOptions, ou ignorez le fichier et journalisez
IronBarCodeEncodingExceptionÉchec d'encodage générique lors de la génération du code-barresVérifiez que les données d'entrée correspondent aux contraintes cibles BarcodeWriterEncoding
IronBarCodeContentTooLongEncodingExceptionLa valeur dépasse la limite de caractères pour la symbologie sélectionnéeRaccourcissez les données ou passez à un format à plus grande capacité (QR, DataMatrix)
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingExceptionCaractères non numériques passés à un format exclusivement numérique (EAN, UPC)Nettoyez l'entrée ou passez à un format alphanumérique (Code128, Code39)
IronBarCodeUnsupportedRendererEncodingExceptionL'encyodage de code-barres sélectionné n'est pas écrivable par IronBarcodeUtilisez l'énumération BarcodeWriterEncoding au lieu de BarcodeEncoding
IronBarCodeParsingExceptionLes données structurées (GS1-128) échouent à la validation lors de l'analyseVérifiez la structure GS1 avec Code128GS1Parser.IsValid() avant l'analyse
IronBarCodeNativeExceptionErreur dans la couche d'interopérabilité native (DLLs manquantes, incompatibilité de plateforme)Vérifiez que les packages NuGet spécifiques à la plateforme sont installés (BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdExceptionArgument de seuil de confiance invalide passé aux options de lectureAssurez-vous que ConfidenceThreshold soit entre 0,0 et 1,0
IronBarCodeUnsupportedExceptionL'opération n'est pas prise en charge dans le contexte actuelConsultez le changelog pour la disponibilité des fonctionnalités dans votre version
IronBarCodeExceptionType de base — capture toute erreur spécifique à IronBarcode non traitée ci-dessusEnregistrez tous les détails de l'exception et escaladez pour investigation

Utilisez des filtres d'exception avec des clauses when pour acheminer les types d'exception qui se chevauchent sans imbrication profonde. Les fichiers manquants génèrent le code d'erreur standard System.IO.FileNotFoundException au lieu de IronBarCodeFileException ; veuillez donc inclure un bloc catch distinct pour ce cas :

Entrée

Un code-barres Code128 codant un numéro de facture (chemin de réussite) et un code-barres d'étiquette d'entrepôt représentant le contenu du PDF manquant (chemin d'échec).

Code-barres Code128 INV-2024-7829 utilisé comme entrée de facture scannée
Code128 barcode representing the content of the missing warehouse-labels.pdf failure path input
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/exception-hierarchy.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}");
}
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
$vbLabelText   $csharpLabel

Sortie

Veuillez noterUn fichier valide correspond au type et à la valeur du code-barres décodé.

Sortie de la console indiquant un décodage réussi du code 128 : [Code 128] INV-2024-7829

Un fichier manquant déclenche FileNotFoundException, acheminé par le bloc catch dédié.

Sortie de la console affichant une exception FileNotFoundException pour le fichier warehouse-labels.pdf manquant

Le filtre when (ex.Message.Contains("DLL")) sur IronBarCodeNativeException redirige les erreurs de dépendance manquante vers un gestionnaire spécifique sans affecter les autres exceptions natives. Cette approche est particulièrement utile dans les déploiements Docker où des packages spécifiques à la plateforme peuvent être manquants.

IronSoftware.Exceptions.LicensingException est généré séparément lorsque la clé de licence est invalide ou manquante. Interceptez cette exception au démarrage de l'application plutôt qu'aux alentours des appels de lecture ou d'écriture individuels.


Comment extraire les détails de diagnostic des lectures ayant échoué ?

Une opération de lecture qui ne renvoie aucun résultat n'est pas une exception ; Elle produit une collection BarcodeResults vide. Le contexte diagnostique est obtenu en inspectant les paramètres d'entrée, les options configurées et tous les résultats partiels renvoyés.

L'objet BarcodeResult fournit des propriétés utiles pour l'analyse post-mortem, notamment BarcodeType, Value, PageNumber et Points (coordonnées des coins). Si des résultats sont présents mais inattendus, vérifiez d'abord BarcodeType par rapport au format attendu et vérifiez le PageNumber.

Entrée

Un BARCODE Code128 encodant un numéro de facture, lu avec ExpectBarcodeTypes défini sur Code128 et QRCode, et ReadingSpeed.Detailed pour une lecture approfondie.

Code-barres Code128 INV-2024-7829 utilisé comme entrée de facture scannée
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/diagnostic-logging.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})");
    }
}
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
$vbLabelText   $csharpLabel

Sortie

Veuillez noterLorsque ExpectBarcodeTypes correspond au BARCODE de l'image, la lecture renvoie le type, la valeur, le numéro de page et la position.

Sortie de la console affichant un décodage réussi du Code128 avec le numéro de page et les coordonnées de position.

Si ExpectBarcodeTypes ne contient pas la symbologie réelle, la lecture renvoie un résultat vide. Le bloc [WARN] enregistre les types configurés, la vitesse de lecture et une action suivante suggérée.

Sortie de la console affichant [WARN] aucun code-barres trouvé avec ExpectBarcodeTypes défini sur Code39 pour une image Code128

Deux schémas communs se dégagent lors des diagnostics. Des résultats vides avec un paramètre ExpectBarcodeTypes étroit signifient souvent que le BARCODE utilise une symbologie différente ; L'extension vers BarcodeEncoding.All permet de le confirmer. Des résultats de décodage inattendus indiquent généralement une mauvaise qualité d'image.

L'application de filtres d'image et la réessai à une vitesse de lecture plus lente résolvent souvent ces problèmes. Vous pouvez également activer l'option RemoveFalsePositive pour éliminer les lectures fantômes provenant d'arrière-plans bruyants.

Comment activer la journalisation détaillée pour les opérations de codes-barres ?

IronBarcode expose une API de journalisation intégrée via IronSoftware.Logger. Définissez le mode de journalisation et le chemin d'accès au fichier avant toute opération sur les codes-barres afin de capturer les résultats de diagnostic internes des pipelines de lecture et d'écriture.

Entrée

Image TIFF de code-barres Code128 utilisée comme cible de lecture lorsque la journalisation détaillée est activée.

L'encodage du code-barres Code128 PROB-SCAN-999 a été utilisé comme entrée de numérisation du problème pour l'exemple de journalisation.
:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/enable-logging.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.");
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.")
$vbLabelText   $csharpLabel

LoggingModes.All capture à la fois les sorties de débogage et la journalisation au niveau des fichiers. Le fichier journal enregistre les étapes de traitement internes, telles que les étapes de prétraitement de l'image, les tentatives de détection de format et les appels d'interopérabilité natifs, qui ne sont pas visibles via l'API publique.

Pour les pipelines de production utilisant un framework de journalisation structurée (Serilog, NLog, Microsoft.Extensions.Logging), l'intégration des opérations IronBarcode dans une couche middleware ajoute des entrées JSON structurées au fichier de journal intégré. Le journaliseur intégré écrit des diagnostics en texte brut utiles pour l'escalade vers le support ; Le wrapper structuré fournit des champs interrogeables pour la pile d'observabilité.

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/structured-wrapper.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
    }
}
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
$vbLabelText   $csharpLabel

La sortie structurée s'intègre directement aux outils d'agrégation de journaux. Transmettez stdout à Fluentd, Datadog ou CloudWatch dans un déploiement conteneurisé. Le champ " temps écoulé " met en évidence les régressions de performance avant qu'elles ne constituent des violations des SLA.

Sortie

Sortie de la console indiquant une lecture de code-barres réussie avec la journalisation détaillée activée et le chemin du fichier journal

Comment déboguer le traitement par lots des codes-barres ?

Traiter plusieurs fichiers en isolant chaque lecture dans son propre bloc try-catch, en enregistrant les résultats pour chaque fichier et en générant un résumé agrégé. Le processus se poursuit malgré les défaillances au lieu de s'arrêter à la première erreur.

Entrée

Quatre des cinq images de Barcodes Code128 issues du répertoire scans/. Le cinquième fichier (scan-05-broken.png) contient des octets non valides qui déclenchent une exception de fichier.

Code128 barcode encoding ITEM-SQ-001

Lot 1 — Numérisation 1

Code128 barcode encoding ITEM-SQ-002

Lot 1 — Numérisation 2

Code128 barcode encoding ITEM-SQ-003

Lot 1 — Numérisation 3

Code128 barcode encoding ITEM-SQ-004

Lot 1 — Numérisation 4

:path=/static-assets/barcode/content-code-examples/how-to/detailed-error-messages/batch-processing.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}");
    }
}
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
$vbLabelText   $csharpLabel

Sortie

Sortie de la console affichant le résumé du traitement par lots : 4 succès, 1 échec, avec les détails de l'erreur concernant le fichier corrompu

Lors de l'exécution, la console affiche une ligne pour chaque code-barres décodé, suivie d'un récapitulatif indiquant le nombre de fichiers, les succès, les lectures vides, les échecs et le temps écoulé. Les erreurs sont listées avec le nom du fichier correspondant et la raison de l'échec.

Le processus distingue trois catégories de résultats : succès (codes-barres trouvés et décodés), fichier vide (fichier lu mais aucun code-barres détecté) et échec (exception levée). Cette distinction est importante car les lectures vides et les échecs nécessitent des réponses différentes. Les lectures vides peuvent nécessiter des paramètres de format plus larges, tandis que les échecs indiquent souvent des problèmes d'infrastructure tels que des fichiers manquants, des ressources verrouillées ou des dépendances natives manquantes.

La liste des erreurs conserve le contexte de chaque fichier pour faciliter l'analyse des causes profondes. Dans un pipeline CI/CD, analysez cette sortie pour définir les codes de sortie (zéro pour un succès complet et non nul lorsque failCount est supérieur à zéro) ou transmettez les détails d'erreur à un système d'alerte.

Pour un débit plus élevé, activez le traitement parallèle en définissant Multithreaded sur true et en ajustant MaxParallelThreads en fonction du nombre de cœurs de processeur disponibles. Maintenez l'isolation par fichier en encapsulant l'itération parallèle dans Parallel.ForEach et en utilisant une collection thread-safe pour la liste des erreurs.


Lecture supplémentaire

Consultez les options de licence lorsque le pipeline sera prêt pour la production.

Questions Fréquemment Posées

Comment puis-je gérer les erreurs dans les opérations de code-barres en utilisant IronBarcode ?

IronBarcode fournit des exceptions typées et une journalisation intégrée pour gérer et traiter efficacement les erreurs dans les opérations de code-barres, garantissant que votre application fonctionne sans problème.

Quelles fonctionnalités IronBarcode offre-t-il pour le débogage des problèmes de code-barres ?

IronBarcode inclut l'extraction de diagnostics et l'isolation d'erreurs par lots prête pour la production, ce qui aide les développeurs à identifier et résoudre efficacement les problèmes liés aux codes-barres.

IronBarcode peut-il enregistrer les erreurs lors du traitement des codes-barres ?

Oui, IronBarcode dispose de capacités de journalisation intégrées qui permettent aux développeurs de capturer et d'enregistrer les détails des erreurs pendant le traitement des codes-barres, facilitant ainsi le débogage.

Que sont les exceptions typées dans IronBarcode ?

Les exceptions typées dans IronBarcode sont des types d'erreurs spécifiques qui fournissent des informations détaillées sur les problèmes d'opérations de code-barres, facilitant le diagnostic et la résolution des problèmes pour les développeurs.

Comment IronBarcode aide-t-il à l'isolation des erreurs par lots ?

IronBarcode offre une isolation des erreurs par lots prête pour la production, ce qui aide à séparer les opérations de code-barres erronées des opérations réussies, simplifiant ainsi la gestion des erreurs dans le traitement par lots.

Existe-t-il un moyen d'extraire des diagnostics des opérations de code-barres en utilisant IronBarcode ?

Oui, IronBarcode fournit des outils d'extraction de diagnostics qui aident les développeurs à recueillir des informations détaillées sur les opérations de code-barres, aidant au dépannage et à la résolution des erreurs.

Curtis Chau
Rédacteur technique

Curtis Chau détient un baccalauréat en informatique (Université de Carleton) et se spécialise dans le développement front-end avec expertise en Node.js, TypeScript, JavaScript et React. Passionné par la création d'interfaces utilisateur intuitives et esthétiquement plaisantes, Curtis aime travailler avec des frameworks modernes ...

Lire la suite
Prêt à commencer?
Nuget Téléchargements 2,143,620 | Version : 2026.4 vient de sortir
Still Scrolling Icon

Vous faites encore défiler ?

Vous voulez une preuve rapidement ? PM > Install-Package BarCode
exécuter un échantillon regarder votre chaîne devenir un code-barres.