エラーを処理し、C#でバーコード操作をデバッグする方法

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

バーコード処理パイプラインは、エラーが発生しても何も通知されない場合があり、結果がゼロと表示されると"バーコードが存在しない"と誤解されることがよくあります。しかし、破損したファイル、パスワードで保護されたPDF、フォーマットの不一致などが原因となっている可能性があります。 適切なログ記録と構造化されたエラー処理を実装することで、これらの障害が明らかになり、実用的な診断情報が得られます。

IronBarcodeは、 IronBarcode名前空間に型付き例外階層、組み込みのログ記録API、および詳細なBarcodeResultプロパティを提供します。 これらのプロパティには、検出されたフォーマット、デコードされた値、ページ番号、およびデコードが成功した各箇所の座標が含まれます。

このハウツーでは、型付き例外を捕捉して解釈する方法、失敗した読み取りから診断コンテキストを抽出する方法、構造化ログを有効にする方法、およびバッチ操作中の障害を分離する方法について説明します。

クイックスタート: バーコードエラーの処理と診断の有効化

読み書き呼び出しを、IronBarcodeの型付き例外をターゲットにしたtry-catchブロックでラップし、静かな失敗の代わりに実行可能なエラーメッセージを表示します。

  1. IronBarcode をNuGetパッケージマネージャでインストール

    PM > Install-Package BarCode
  2. このコード スニペットをコピーして実行します。

    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. 実際の環境でテストするためにデプロイする

    今日プロジェクトで IronBarcode を使い始めましょう無料トライアル

    arrow pointer

IronBarcodeの例外を捕捉して解釈するにはどうすればよいですか?

IronBarcodeの例外を、最も具体的なものから最も一般的なものまで捕捉します。 ファイルエラー、PDFパスワードエラー、エンコードエラーなど、処理が必要な例外を最初に処理するcatchブロックを配置し、その後に基本型を配置します。 IronBarcodeの.Exceptions名前空間は、それぞれ特定の障害モードに対応する11種類の例外タイプを定義しています。

IronBarcode例外タイプ—原因と推奨修正
例外タイプトリガー推奨される修正
IronBarCodeFileExceptionファイルが破損しているか、ロックされているか、またはサポートされていない画像形式です。ファイルがサポートされている画像形式であり、ロックされていないことを検証します。また、ファイルが見つからない場合は、 FileNotFoundExceptionを別途キャッチします。
IronBarCodePdfPasswordExceptionPDFがパスワードで保護されているか暗号化されているパスワードをPdfBarcodeReaderOptionsを通じて提供するか、ファイルをスキップしてログを記録します
IronBarCodeEncodingExceptionバーコード生成中の一般的なエンコーディングエラー入力データが目的のBarcodeWriterEncoding制約と一致することを確認します
IronBarCodeContentTooLongEncodingException選択されたシンボロジーで文字数制限を超えるデータを切り詰めるか、より高容量のフォーマット(QR, DataMatrix)に切り替えます
IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException数値のみのフォーマット(EAN, UPC)に非数値文字を渡す入力をサニタイズするか、英数字フォーマット(Code128, Code39)に切り替えます
IronBarCodeUnsupportedRendererEncodingException選択されたBarcodeEncodingはIronBarcodeで書き出せませんBarcodeEncodingの代わりにBarcodeWriterEncoding列挙型を使用します
IronBarCodeParsingExceptionパース中に構造化データ(GS1-128)が検証に失敗するパース前にCode128GS1Parser.IsValid()を使ってGS1構造を検証します
IronBarCodeNativeExceptionネイティブ相互運用層でのエラー(DLLが見つからない、プラットフォームの互換性)プラットフォーム固有のNuGetパッケージがインストールされていることを確認します(BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdException無効な信頼度しきい値引数がリーダーオプションに渡されているConfidenceThresholdが0.0から1.0の間であることを確認します
IronBarCodeUnsupportedException現在のコンテキストではサポートされていない操作変更履歴で、お使いのバージョンでの機能の利用可否を確認します
IronBarCodeException基本タイプ — 上記に一致しないすべてのIronBarcode固有のエラーをキャッチします完全な例外詳細をログに記録し、調査のためにエスカレーションします

when 句を含む例外フィルターを使用して、深いネスト構造を生成することなく、重複する例外タイプをルーティングします。 ファイルが見つからない場合、IronBarCodeFileException ではなく標準の System.IO.FileNotFoundException がスローされるため、このケース用に別の catch ブロックを含めてください:

入力

請求書番号をエンコードしたCode128バーコード(成功経路)と、欠落したPDFの内容を表す倉庫ラベルバーコード(失敗経路)。

スキャンされた請求書の入力として使用されるCode128バーコードエンコーディングINV-2024-7829
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

出力

ご注意有効なファイルは、デコードされたバーコードの種類と値に解決されます。

コンソール出力:Code128デコード成功を示す:[Code128] INV-2024-7829

ファイルが見つからない場合、FileNotFoundExceptionが発生し、専用のcatchブロックによって処理されます。

コンソール出力には、見つからない warehouse-labels.pdf ファイルに対する FileNotFoundException が表示されています。

when (ex.Message.Contains("DLL")) フィルターは、IronBarCodeNativeException において、依存関係の欠如によるエラーを他のネイティブ例外に影響を与えることなく、特定のハンドラーに転送します。 この方法は、プラットフォーム固有のパッケージが不足している可能性があるDocker環境において特に有効です。

IronSoftware.Exceptions.LicensingException は、ライセンスキーが無効であるか、存在しない場合に別途スローされます。 この例外は、個々の読み取りまたは書き込み呼び出しの前後ではなく、アプリケーションの起動時に捕捉してください。


読み取り失敗から診断の詳細を抽出するにはどうすればよいですか?

読み取り操作で結果がゼロ件返されることは例外ではありません。 空の BarcodeResults コレクションが生成されます。 診断コンテキストは、入力パラメータ、設定済みオプション、および返された部分的な結果を検査することによって取得されます。

BarcodeResult オブジェクトは、PageNumber、および Points (コーナー座標)など、事後分析に役立つプロパティを提供します。 結果が表示されているものの予期しない内容である場合は、まず BarcodeType を期待される形式と照らし合わせ、PageNumber を確認してください。

入力

請求書番号をエンコードしたCode128 BARCODE。ReadingSpeed.Detailedを使用して確実にスキャンできるように読み取ります。

スキャンされた請求書の入力として使用されるCode128バーコードエンコーディングINV-2024-7829
: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

出力

ExpectBarcodeTypesが画像内のBARCODEと一致すると、読み取り結果はタイプ、値、ページ番号、および位置を返します。

コンソール出力には、ページ番号と位置座標を含むCode128デコード成功の表示があります。

ExpectBarcodeTypes に実際のシンボルが含まれていない場合、読み取りは空の結果を返します。 [WARN] ブロックには、設定されたタイプ、読み取り速度、および推奨される次のアクションがログに記録されます。

コンソール出力には、[WARN] Code128イメージに対してExpectBarcodeTypesがCode39に設定されているため、バーコードが見つかりませんでしたと表示されます。

診断の過程で、2つの共通パターンが現れる。 ExpectBarcodeTypes の設定が狭い場合に結果が空になるのは、BARCODEが別のシンボロジーを使用していることを意味することがよくあります。 BarcodeEncoding.All を参照すれば、これを確認できます。 予期しないデコード結果は、通常、画質の悪さを示しています。

画像フィルターを適用し、読み込み速度を遅くして再試行すると、これらの問題は解決することがよくあります。 また、RemoveFalsePositive オプションを切り替えることで、ノイズの多い背景からのファントムリードを除去することもできます。

バーコード操作の詳細ログを有効にするにはどうすればよいですか?

IronBarcodeは、IronSoftware.Loggerを通じて組み込みのロギングAPIを提供します。 読み取りおよび書き込みパイプラインからの内部診断出力を取得するには、バーコード操作を行う前にログモードとファイルパスを設定してください。

入力

詳細ログが有効になっている場合、読み取り対象としてCode128バーコードのTIFF画像が使用されます。

Code128バーコードエンコーディングPROB-SCAN-999は、ログ記録例の問題スキャン入力として使用されます。
: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 は、デバッグ出力とファイルレベルのログの両方をキャプチャします。 ログファイルには、画像の前処理段階、フォーマット検出の試行、ネイティブ相互運用呼び出しなど、公開APIからは見えない内部処理手順が記録されます。

構造化ロギングフレームワーク(Serilog、NLog、Microsoft.Extensions.Logging)を使用する本番環境のパイプラインにおいて、IronBarcodeの操作をミドルウェア層でラップすることで、組み込みのログファイルに加えて構造化されたJSONエントリが追加されます。組み込みのロガーは、サポートへのエスカレーションに役立つプレーンテキスト形式の診断情報を書き込みます; 構造化されたラッパーは、オブザーバビリティスタックに対してクエリ可能なフィールドを提供する。

: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

構造化された出力は、ログ集約ツールと直接統合されます。 コンテナ化された環境において、Pipe stdout を Fluentd、Datadog、または CloudWatch に送信します。 経過時間フィールドは、パフォーマンスの低下がSLA違反となる前にそれを明らかにする。

出力

詳細なログ記録が有効になっている状態でバーコードの読み取りが成功したことを示すコンソール出力とログファイルのパス

バッチバーコード処理のデバッグ方法を教えてください

複数のファイルを処理するには、各読み込み処理を個別のtry-catchブロックで分離し、各ファイルの結果を記録し、集計サマリーを生成します。 パイプラインは最初のエラーで停止するのではなく、障害が発生しても処理を継続します。

入力

scans/ バッチディレクトリにある 5 つの Code128 BARCODE 画像のうち 4 つ。 5番目のファイル(scan-05-broken.png)には、ファイル例外を引き起こす無効なバイトが含まれています。

Code128 barcode encoding ITEM-SQ-001

バッチ1 — スキャン1

Code128 barcode encoding ITEM-SQ-002

バッチ1 — スキャン2

Code128 barcode encoding ITEM-SQ-003

バッチ1 — スキャン3

Code128 barcode encoding ITEM-SQ-004

バッチ1 — スキャン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

出力

バッチの概要を示すコンソール出力:成功4件、失敗1件、破損ファイルのエラー詳細

実行中、コンソールにはデコードされたバーコードごとに1行が出力され、その後にファイル数、成功数、空の読み取り数、失敗数、経過時間を含む概要が表示されます。エラーは、対応するファイル名と失敗理由とともに一覧表示されます。

このプロセスでは、成功(バーコードが見つかり、デコードされた)、空(ファイルは読み取られたがバーコードが検出されなかった)、失敗(例外が発生した)の3つの結果カテゴリが区別されます。 この区別は重要です。なぜなら、空の読み取りとエラーには異なる対応が必要となるからです。 空の読み取りが発生する場合は、より広範なフォーマット設定が必要になる可能性があり、エラーが発生する場合は、ファイルの欠落、リソースのロック、ネイティブ依存関係の欠落など、インフラストラクチャの問題を示していることが多い。

エラーリストは、根本原因分析を支援するために、ファイルごとのコンテキストを保持します。 CI/CDパイプラインでは、この出力を解析して終了コード(完全成功の場合はゼロ、failCountがゼロより大きい場合はゼロ以外)を設定するか、エラーの詳細をアラートシステムに転送します。

処理能力を高めるには、Multithreadedtrue に設定し、利用可能な CPU コア数に合わせて MaxParallelThreads を調整することで、並列処理を有効にしてください。 並列処理を Parallel.ForEach でラップし、エラーリストにスレッドセーフなコレクションを使用することで、ファイルごとの分離を維持します。


さらなる読み物

パイプラインが本番稼働準備完了になったら、ライセンスオプションを確認してください

よくある質問

How can I handle errors in barcode operations using IronBarcode?

IronBarcode provides typed exceptions and built-in logging to efficiently manage and handle errors in barcode operations, ensuring your application runs smoothly.

What features does IronBarcode offer for debugging barcode issues?

IronBarcode includes diagnostic extraction and production-ready batch error isolation, which assist developers in identifying and resolving barcode-related issues efficiently.

Can IronBarcode log errors during barcode processing?

Yes, IronBarcode has built-in logging capabilities that allow developers to capture and log error details during barcode processing, facilitating easier debugging.

What are typed exceptions in IronBarcode?

Typed exceptions in IronBarcode are specific error types that provide detailed information about barcode operation issues, making it easier for developers to diagnose and fix problems.

How does IronBarcode assist with batch error isolation?

IronBarcode offers production-ready batch error isolation, which helps in separating erroneous barcode operations from successful ones, streamlining error management in batch processing.

Is there a way to extract diagnostics from barcode operations using IronBarcode?

Yes, IronBarcode provides diagnostic extraction tools that help developers gather detailed information about barcode operations, aiding in troubleshooting and error resolution.

カーティス・チャウ
テクニカルライター

Curtis Chauは、カールトン大学でコンピュータサイエンスの学士号を取得し、Node.js、TypeScript、JavaScript、およびReactに精通したフロントエンド開発を専門としています。直感的で美しいユーザーインターフェースを作成することに情熱を持ち、Curtisは現代のフレームワークを用いた開発や、構造の良い視覚的に魅力的なマニュアルの作成を楽しんでいます。

開発以外にも、CurtisはIoT(Internet of Things)への強い関心を持ち、ハードウェアとソフトウェアの統合方法を模索しています。余暇には、ゲームをしたりDiscordボットを作成したりして、技術に対する愛情と創造性を組み合わせています。

準備はできましたか?
Nuget ダウンロード 2,143,620 | バージョン: 2026.4 リリース
Still Scrolling Icon

まだスクロールしていますか?

すぐに証拠が欲しいですか? PM > Install-Package BarCode
サンプルを実行する 文字列が BarCode になるのを見る。