# How to Handle Errors and Debug Barcode Operations in C#
Barcode processing pipelines can fail silently, with zero results often mistaken for 'no barcode present.' However, issues like corrupted files, password-protected PDFs, or format mismatches may be responsible. Implementing proper logging and structured error handling uncovers these failures and provides actionable diagnostics.
IronBarcode offers a typed exception hierarchy in the `IronBarCode.Exceptions` namespace, a built-in logging API, and detailed `BarcodeResult` properties. These properties include the detected format, decoded value, page number, and coordinates for each successful decode.
This how-to explains how to catch and interpret typed exceptions, extract diagnostic context from failed reads, enable structured logging, and isolate failures during batch operations.
*as-heading:2(Quickstart: Handle Barcode Errors and Enable Diagnostics)*
Wrap read/write calls in try-catch blocks targeting IronBarcode's typed exceptions to surface actionable error messages instead of silent failures.
```cs
:title=Handle Barcode Errors and Enable Diagnostics
using IronBarCode;
using IronBarCode.Exceptions;
try
{
BarcodeResults results = BarcodeReader.Read("label.pdf");
Console.WriteLine($"Found {results.Count} barcode(s)");
}
catch (IronBarCodeFileException ex)
{
Console.Error.WriteLine($"File error: {ex.Message}");
}
```
<div class="hsg-featured-snippet">
<h2>How to Handle Barcode Errors and Enable Diagnostics with IronBarcode</h2>
<ol>
<li><a class="js-modal-open" data-modal-id="trial-license-after-download" href="https://nuget.org/packages/BarCode/">Download the IronBarcode library from NuGet</a></li>
<li>Wrap read/write calls in try-catch blocks targeting specific exception types</li>
<li>Inspect <code>BarcodeResults</code> for empty or low-confidence entries after a successful read</li>
<li>Enable <code>IronSoftware.Logger</code> to capture internal diagnostic output</li>
<li>Isolate failures per file in batch operations with continue-on-error logic</li>
</ol>
</div>
## How Do I Catch and Interpret IronBarcode Exceptions?
Catch IronBarcode exceptions from the most specific to the most general. Order catch blocks to handle actionable exceptions first, such as file, PDF password, and encoding errors, followed by the base type. The `IronBarCode.Exceptions` namespace defines 11 exception types, each corresponding to a specific failure mode:
<div class="content__data-table" data-content-table>
<table>
<caption>IronBarcode Exception Types - Causes and Recommended Fixes</caption>
<thead>
<tr><th>Exception Type</th><th>Trigger</th><th>Recommended Fix</th></tr>
</thead>
<tbody>
<tr><td><code>IronBarCodeFileException</code></td><td>File is corrupted, locked, or in an unsupported image format</td><td>Validate the file is a supported image format and is not locked; also catch <code>FileNotFoundException</code> separately for missing files</td></tr>
<tr><td><code>IronBarCodePdfPasswordException</code></td><td>PDF is password-protected or encrypted</td><td>Supply password via <code>PdfBarcodeReaderOptions</code>, or skip file and log</td></tr>
<tr><td><code>IronBarCodeEncodingException</code></td><td>Generic encoding failure during barcode generation</td><td>Verify input data matches the target <code>BarcodeWriterEncoding</code> constraints</td></tr>
<tr><td><code>IronBarCodeContentTooLongEncodingException</code></td><td>Value exceeds the character limit for the selected symbology</td><td>Truncate data or switch to a higher-capacity format (QR, DataMatrix)</td></tr>
<tr><td><code>IronBarCodeFormatOnlyAcceptsNumericValuesEncodingException</code></td><td>Non-numeric characters passed to a numeric-only format (EAN, UPC)</td><td>Sanitize input or switch to an alphanumeric format (Code128, Code39)</td></tr>
<tr><td><code>IronBarCodeUnsupportedRendererEncodingException</code></td><td>Selected <code>BarcodeEncoding</code> is not writable by IronBarcode</td><td>Use <code>BarcodeWriterEncoding</code> enum instead of <code>BarcodeEncoding</code></td></tr>
<tr><td><code>IronBarCodeParsingException</code></td><td>Structured data (GS1-128) fails validation during parsing</td><td>Validate GS1 structure with <code>Code128GS1Parser.IsValid()</code> before parsing</td></tr>
<tr><td><code>IronBarCodeNativeException</code></td><td>Error in native interop layer (missing DLLs, platform incompatibility)</td><td>Verify platform-specific NuGet packages are installed (BarCode.Linux, BarCode.macOS)</td></tr>
<tr><td><code>IronBarCodeConfidenceThresholdException</code></td><td>Invalid confidence threshold argument passed to reader options</td><td>Ensure <code>ConfidenceThreshold</code> is between 0.0 and 1.0</td></tr>
<tr><td><code>IronBarCodeUnsupportedException</code></td><td>Operation not supported in the current context</td><td>Check the <a href="https://ironsoftware.com/csharp/barcode/product-updates/changelog/">changelog</a> for feature availability in your version</td></tr>
<tr><td><code>IronBarCodeException</code></td><td>Base type - catches any IronBarcode-specific error not matched above</td><td>Log full exception details and escalate for investigation</td></tr>
</tbody>
</table>
</div>
Use exception filters with `when` clauses to route overlapping exception types without deep nesting. Missing files throw the standard `System.IO.FileNotFoundException` instead of `IronBarCodeFileException`, so include a separate catch block for this case:
### Input
A Code128 barcode encoding an invoice number (success path) and a warehouse label barcode representing the content of the missing PDF (failure path).
<div class="competitors-section__wrapper-even-1">
<div class="competitors__card" style="width: 45%;">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-invoice.png"
alt="Code128 barcode encoding INV-2024-7829 used as the scanned invoice input"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
scanned-invoice.png (success path)
</p>
</div>
<div class="competitors__card" style="width: 45%;">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-warehouse-labels.png"
alt="Code128 barcode representing the content of the missing warehouse-labels.pdf failure path input"
class="img-responsive add-shadow" />
<p class="competitors__download-link" style="color: #181818; font-style: italic;">
warehouse-labels.pdf (failure path - file not present on disk)
</p>
</div>
</div>
```cs
using IronBarCode;
using IronBarCode.Exceptions;
// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";
try
{
BarcodeResults results = BarcodeReader.Read(filePath);
foreach (BarcodeResult result in results)
{
// Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
}
}
catch (IronBarCodePdfPasswordException ex)
{
// PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
// File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
// Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
// The when filter routes only missing-DLL errors here; other native exceptions
// fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
// Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
```
### Output
[[i:(A valid file resolves to the decoded barcode type and value.)]]
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-exception-hierarchy-success.webp" alt="Console output showing successful Code128 decode: [Code128] INV-2024-7829" class="img-responsive add-shadow" />
</div>
</div>
A missing file triggers `FileNotFoundException`, routed by the dedicated catch block.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-exception-hierarchy-failure.webp" alt="Console output showing FileNotFoundException for the missing warehouse-labels.pdf file" class="img-responsive add-shadow" />
</div>
</div>
The `when (ex.Message.Contains("DLL"))` filter on `IronBarCodeNativeException` directs missing-dependency errors to a specific handler without affecting other native exceptions. This approach is especially useful in Docker deployments where platform-specific packages may be missing.
`IronSoftware.Exceptions.LicensingException` is thrown separately when the license key is invalid or missing. Catch this exception at application startup instead of around individual read or write calls.
---
## How Do I Extract Diagnostic Details from Failed Reads?
A read operation that returns zero results is not an exception; it produces an empty `BarcodeResults` collection. Diagnostic context is obtained by inspecting input parameters, configured options, and any partial results returned.
The `BarcodeResult` object provides properties useful for post-mortem analysis, including `BarcodeType`, `Value`, `PageNumber`, and `Points` (corner coordinates). If results are present but unexpected, first check `BarcodeType` against the expected format and verify the `PageNumber`.
### Input
A Code128 barcode encoding an invoice number, read with `ExpectBarcodeTypes` set to `Code128` and `QRCode`, and `ReadingSpeed.Detailed` for thorough scanning.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-invoice.png" alt="Code128 barcode encoding INV-2024-7829 used as the scanned invoice input" class="img-responsive add-shadow" />
</div>
</div>
```cs
using IronBarCode;
string filePath = "scanned-invoice.png";
// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
Speed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged images
ExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match
};
BarcodeResults results = BarcodeReader.Read(filePath, options);
// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
// Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");
Console.Error.WriteLine($" Speed: {options.Speed}");
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
foreach (BarcodeResult result in results)
{
// Points contains the four corner coordinates of the barcode in the image;
// use the first corner as a representative position indicator
string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
+ $"(Page: {result.PageNumber}, Position: {pos})");
}
}
```
### Output
[[i:(When `ExpectBarcodeTypes` matches the barcode in the image, the read returns the type, value, page number, and position.)]]
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-diagnostic-logging-success.webp" alt="Console output showing successful Code128 decode with page number and position coordinates" class="img-responsive add-shadow" />
</div>
</div>
If `ExpectBarcodeTypes` does not include the actual symbology, the read returns an empty result. The [WARN] block logs the configured types, reading speed, and a suggested next action.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-diagnostic-logging-failure.webp" alt="Console output showing [WARN] no barcodes found with ExpectBarcodeTypes set to Code39 for a Code128 image" class="img-responsive add-shadow" />
</div>
</div>
Two common patterns emerge during diagnostics. Empty results with a narrow `ExpectBarcodeTypes` setting often mean the barcode uses a different symbology; expanding to `BarcodeEncoding.All` can confirm this. Unexpected decode results usually point to poor image quality.
Applying image filters and retrying with a slower reading speed often resolves these issues. You can also toggle the `RemoveFalsePositive` option to eliminate phantom reads from noisy backgrounds.
## How Do I Enable Verbose Logging for Barcode Operations?
IronBarcode exposes a built-in logging API through `IronSoftware.Logger`. Set the logging mode and file path before any barcode operations to capture internal diagnostic output from the read and write pipelines.
### Input
A Code128 barcode TIFF image used as the read target while verbose logging is active.
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-problem-scan.png" alt="Code128 barcode encoding PROB-SCAN-999 used as the problem scan input for the logging example" class="img-responsive add-shadow" />
</div>
</div>
```cs
using IronBarCode;
// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory
// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Detailed,
ExpectBarcodeTypes = BarcodeEncoding.All // scan for every supported symbology
};
BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
```
`LoggingModes.All` captures both debug output and file-level logging. The log file records internal processing steps, such as image pre-processing stages, format detection attempts, and native interop calls, which are not visible through the public API.
For production pipelines using a structured logging framework (Serilog, NLog, `Microsoft.Extensions.Logging`), wrapping IronBarcode operations in a middleware layer adds structured JSON entries alongside the built-in log file. The built-in logger writes plain-text diagnostics useful for support escalation; the structured wrapper provides queryable fields for the observability stack.
```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
}
}
```
The structured output integrates directly with log aggregation tools. Pipe `stdout` to Fluentd, Datadog, or CloudWatch in a containerized deployment. The elapsed-time field highlights performance regressions before they become SLA violations.
### Output
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-enable-logging.webp" alt="Console output showing a successful barcode read with verbose logging enabled and the log file path" class="img-responsive add-shadow" />
</div>
</div>
---
## How Do I Debug Batch Barcode Processing?
Process multiple files by isolating each read in its own try-catch block, recording outcomes for each file, and generating an aggregate summary. The pipeline continues through failures instead of stopping at the first error.
### Input
Four of the five Code128 barcode images from the `scans/` batch directory. The fifth file (`scan-05-broken.png`) contains invalid bytes to trigger a file exception.
<div style="display: flex; gap: 1rem; justify-content: center; flex-wrap: wrap;">
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-one.png"
alt="Code128 barcode encoding ITEM-SQ-001"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Batch 1 - Scan 1</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-two.png"
alt="Code128 barcode encoding ITEM-SQ-002"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Batch 1 - Scan 2</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-three.png"
alt="Code128 barcode encoding ITEM-SQ-003"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Batch 1 - Scan 3</p>
</div>
</div>
<div class="content-img-align-center" style="width: 22.5%;">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/input-batch-scan-four.png"
alt="Code128 barcode encoding ITEM-SQ-004"
class="img-responsive add-shadow" />
<p style="color: #181818; font-style: italic; text-align: center;">Batch 1 - Scan 4</p>
</div>
</div>
</div>
```cs
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;
// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";
// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced, // balances throughput vs accuracy
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
ExpectMultipleBarcodes = true // scan each file fully
};
// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();
foreach (string file in files)
{
try
{
BarcodeResults results = BarcodeReader.Read(file, options);
// Empty result is not an exception — the file was read but contained no matching barcode
if (results == null || results.Count == 0)
{
emptyCount++;
errors.Add((file, "No barcodes detected")); // record so caller can adjust options
continue;
}
foreach (BarcodeResult result in results)
{
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
}
successCount++;
}
catch (IronBarCodePdfPasswordException)
{
// PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount++;
errors.Add((file, "Password-protected PDF"));
}
catch (IronBarCodeFileException ex)
{
// File is corrupted, locked, or in an unsupported image format
failCount++;
errors.Add((file, $"File error: {ex.Message}"));
}
catch (FileNotFoundException ex)
{
// File was in the directory listing but deleted before the read completed (race condition)
failCount++;
errors.Add((file, $"File not found: {ex.Message}"));
}
catch (IronBarCodeException ex)
{
// Catch-all for any other IronBarcode-specific errors not handled above
failCount++;
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
}
catch (Exception ex)
{
// Unexpected non-IronBarcode error — log the full type for investigation
failCount++;
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
}
}
sw.Stop();
// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files: {files.Length}");
Console.WriteLine($"Success: {successCount}");
Console.WriteLine($"Empty reads: {emptyCount}");
Console.WriteLine($"Failures: {failCount}");
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");
if (errors.Any())
{
Console.WriteLine("\n--- Error Details ---");
foreach (var (errorFile, errorMsg) in errors)
{
Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}");
}
}
```
### Output
<div class="content-img-align-center">
<div class="center-image-wrapper">
<img src="/static-assets/barcode/how-to/detailed-error-messages/output-batch-processing.webp" alt="Console output showing the batch summary: 4 successes, 1 failure, with error details for the corrupted file" class="img-responsive add-shadow" />
</div>
</div>
During execution, the console outputs one line for each decoded barcode, followed by a summary with file count, successes, empty reads, failures, and elapsed time. Errors are listed with their corresponding file names and reasons for failure.
The process distinguishes three outcome categories: success (barcodes found and decoded), empty (file read but no barcodes detected), and failure (exception thrown). This distinction matters because empty reads and failures require different responses. Empty reads may need broader format settings, while failures often indicate infrastructure issues such as missing files, locked resources, or missing native dependencies.
The error list maintains per-file context to support root cause analysis. In a CI/CD pipeline, parse this output to set exit codes (zero for complete success and non-zero when `failCount` is greater than zero) or forward error details to an alerting system.
For higher throughput, enable parallel processing by setting `Multithreaded` to `true` and adjusting `MaxParallelThreads` to match available CPU cores. Maintain per-file isolation by wrapping the parallel iteration in `Parallel.ForEach` and using a thread-safe collection for the error list.
---
## Further Reading
- [IronBarcode Tutorials: Reading Barcodes](https://ironsoftware.com/csharp/barcode/tutorials/reading-barcodes/): end-to-end reading walkthroughs.
- [False Positive Prevention](https://ironsoftware.com/csharp/barcode/troubleshooting/false-positives/): reducing phantom reads in noisy images.
- [Image Correction How-To](https://ironsoftware.com/csharp/barcode/how-to/image-correction/): filters that improve read accuracy.
- [Docker Setup Guide](https://ironsoftware.com/csharp/barcode/get-started/docker-linux/): containerized deployment with correct native dependencies.
- [BarcodeReaderOptions API Reference](https://ironsoftware.com/csharp/barcode/object-reference/api/IronBarCode.BarcodeReaderOptions.html): complete configuration documentation.
- [IronBarcode Changelog](https://ironsoftware.com/csharp/barcode/product-updates/changelog/): version-specific fixes and feature additions.
[View licensing options](https://ironsoftware.com/csharp/barcode/licensing/) when the pipeline is ready for production.
Barcode processing pipelines can fail silently, with zero results often mistaken for 'no barcode present.' However, issues like corrupted files, password-protected PDFs, or format mismatches may be responsible. Implementing proper logging and structured error handling uncovers these failures and provides actionable diagnostics.
IronBarcode offers a typed exception hierarchy in the IronBarCode.Exceptions namespace, a built-in logging API, and detailed BarcodeResult properties. These properties include the detected format, decoded value, page number, and coordinates for each successful decode.
This how-to explains how to catch and interpret typed exceptions, extract diagnostic context from failed reads, enable structured logging, and isolate failures during batch operations.
Quickstart: Handle Barcode Errors and Enable Diagnostics
Wrap read/write calls in try-catch blocks targeting IronBarcode's typed exceptions to surface actionable error messages instead of silent failures.
Wrap read/write calls in try-catch blocks targeting specific exception types
Inspect BarcodeResults for empty or low-confidence entries after a successful read
Enable IronSoftware.Logger to capture internal diagnostic output
Isolate failures per file in batch operations with continue-on-error logic
How Do I Catch and Interpret IronBarcode Exceptions?
Catch IronBarcode exceptions from the most specific to the most general. Order catch blocks to handle actionable exceptions first, such as file, PDF password, and encoding errors, followed by the base type. The IronBarCode.Exceptions namespace defines 11 exception types, each corresponding to a specific failure mode:
IronBarcode Exception Types - Causes and Recommended Fixes
Exception Type
Trigger
Recommended Fix
IronBarCodeFileException
File is corrupted, locked, or in an unsupported image format
Validate the file is a supported image format and is not locked; also catch FileNotFoundException separately for missing files
IronBarCodePdfPasswordException
PDF is password-protected or encrypted
Supply password via PdfBarcodeReaderOptions, or skip file and log
IronBarCodeEncodingException
Generic encoding failure during barcode generation
Verify input data matches the target BarcodeWriterEncoding constraints
IronBarCodeContentTooLongEncodingException
Value exceeds the character limit for the selected symbology
Truncate data or switch to a higher-capacity format (QR, DataMatrix)
Non-numeric characters passed to a numeric-only format (EAN, UPC)
Sanitize input or switch to an alphanumeric format (Code128, Code39)
IronBarCodeUnsupportedRendererEncodingException
Selected BarcodeEncoding is not writable by IronBarcode
Use BarcodeWriterEncoding enum instead of BarcodeEncoding
IronBarCodeParsingException
Structured data (GS1-128) fails validation during parsing
Validate GS1 structure with Code128GS1Parser.IsValid() before parsing
IronBarCodeNativeException
Error in native interop layer (missing DLLs, platform incompatibility)
Verify platform-specific NuGet packages are installed (BarCode.Linux, BarCode.macOS)
IronBarCodeConfidenceThresholdException
Invalid confidence threshold argument passed to reader options
Ensure ConfidenceThreshold is between 0.0 and 1.0
IronBarCodeUnsupportedException
Operation not supported in the current context
Check the changelog for feature availability in your version
IronBarCodeException
Base type - catches any IronBarcode-specific error not matched above
Log full exception details and escalate for investigation
Use exception filters with when clauses to route overlapping exception types without deep nesting. Missing files throw the standard System.IO.FileNotFoundException instead of IronBarCodeFileException, so include a separate catch block for this case:
Input
A Code128 barcode encoding an invoice number (success path) and a warehouse label barcode representing the content of the missing PDF (failure path).
scanned-invoice.png (success path)
warehouse-labels.pdf (failure path - file not present on disk)
using IronBarCode;using IronBarCode.Exceptions;// Success path: valid file present on diskstring filePath = "scanned-invoice.png";// Failure path: file does not exist → caught by FileNotFoundException below// string filePath = "warehouse-labels.pdf";try{ BarcodeResults results = BarcodeReader.Read(filePath); foreach (BarcodeResult result in results) { // Print the detected symbology and decoded value for each barcode foundConsole.WriteLine($"[{result.BarcodeType}] {result.Value}"); }}catch (IronBarCodePdfPasswordException ex){ // PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retryingConsole.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");}catch (IronBarCodeFileException ex){ // File is present but corrupted, locked, or in an unsupported formatConsole.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");}catch (FileNotFoundException ex){ // Missing files throw FileNotFoundException, not IronBarCodeFileExceptionConsole.Error.WriteLine($"File not found: {filePath} — {ex.Message}");}catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL")){ // The when filter routes only missing-DLL errors here; other native exceptions // fall through to the IronBarCodeException block belowConsole.Error.WriteLine($"Missing native dependency: {ex.Message}");}catch (IronBarCodeException ex){ // Base catch for any IronBarcode-specific error not matched by the blocks aboveConsole.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");}
using IronBarCode;
using IronBarCode.Exceptions;
// Success path: valid file present on disk
string filePath = "scanned-invoice.png";
// Failure path: file does not exist → caught by FileNotFoundException below
// string filePath = "warehouse-labels.pdf";
try
{
BarcodeResults results = BarcodeReader.Read(filePath);
foreach (BarcodeResult result in results)
{
// Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}");
}
}
catch (IronBarCodePdfPasswordException ex)
{
// PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}");
}
catch (IronBarCodeFileException ex)
{
// File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}");
}
catch (FileNotFoundException ex)
{
// Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}");
}
catch (IronBarCodeNativeException ex) when (ex.Message.Contains("DLL"))
{
// The when filter routes only missing-DLL errors here; other native exceptions
// fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}");
}
catch (IronBarCodeException ex)
{
// Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}");
}
ImportsIronBarCodeImportsIronBarCode.Exceptions' Success path: valid file present on diskDim filePath AsString = "scanned-invoice.png"' Failure path: file does not exist → caught by FileNotFoundException below' Dim filePath As String = "warehouse-labels.pdf"Try Dim results AsBarcodeResults = BarcodeReader.Read(filePath) For Each result AsBarcodeResultIn results ' Print the detected symbology and decoded value for each barcode foundConsole.WriteLine($"[{result.BarcodeType}] {result.Value}") NextCatch ex AsIronBarCodePdfPasswordException ' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retryingConsole.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")Catch ex AsIronBarCodeFileException ' File is present but corrupted, locked, or in an unsupported formatConsole.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")Catch ex AsFileNotFoundException ' Missing files throw FileNotFoundException, not IronBarCodeFileExceptionConsole.Error.WriteLine($"File not found: {filePath} — {ex.Message}")Catch ex AsIronBarCodeNativeExceptionWhen ex.Message.Contains("DLL") ' The when filter routes only missing-DLL errors here; other native exceptions ' fall through to the IronBarCodeException block belowConsole.Error.WriteLine($"Missing native dependency: {ex.Message}")Catch ex AsIronBarCodeException ' Base catch for any IronBarcode-specific error not matched by the blocks aboveConsole.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")EndTry
Imports IronBarCode
Imports IronBarCode.Exceptions
' Success path: valid file present on disk
Dim filePath As String = "scanned-invoice.png"
' Failure path: file does not exist → caught by FileNotFoundException below
' Dim filePath As String = "warehouse-labels.pdf"
Try
Dim results As BarcodeResults = BarcodeReader.Read(filePath)
For Each result As BarcodeResult In results
' Print the detected symbology and decoded value for each barcode found
Console.WriteLine($"[{result.BarcodeType}] {result.Value}")
Next
Catch ex As IronBarCodePdfPasswordException
' PDF is encrypted — supply the password via PdfBarcodeReaderOptions before retrying
Console.Error.WriteLine($"PDF requires password: {filePath} — {ex.Message}")
Catch ex As IronBarCodeFileException
' File is present but corrupted, locked, or in an unsupported format
Console.Error.WriteLine($"Cannot read file: {filePath} — {ex.Message}")
Catch ex As FileNotFoundException
' Missing files throw FileNotFoundException, not IronBarCodeFileException
Console.Error.WriteLine($"File not found: {filePath} — {ex.Message}")
Catch ex As IronBarCodeNativeException When ex.Message.Contains("DLL")
' The when filter routes only missing-DLL errors here; other native exceptions
' fall through to the IronBarCodeException block below
Console.Error.WriteLine($"Missing native dependency: {ex.Message}")
Catch ex As IronBarCodeException
' Base catch for any IronBarcode-specific error not matched by the blocks above
Console.Error.WriteLine($"IronBarcode error: {ex.GetType().Name} — {ex.Message}")
End Try
Output
Please note: A valid file resolves to the decoded barcode type and value.
A missing file triggers FileNotFoundException, routed by the dedicated catch block.
The when (ex.Message.Contains("DLL")) filter on IronBarCodeNativeException directs missing-dependency errors to a specific handler without affecting other native exceptions. This approach is especially useful in Docker deployments where platform-specific packages may be missing.
IronSoftware.Exceptions.LicensingException is thrown separately when the license key is invalid or missing. Catch this exception at application startup instead of around individual read or write calls.
How Do I Extract Diagnostic Details from Failed Reads?
A read operation that returns zero results is not an exception; it produces an empty BarcodeResults collection. Diagnostic context is obtained by inspecting input parameters, configured options, and any partial results returned.
The BarcodeResult object provides properties useful for post-mortem analysis, including BarcodeType, Value, PageNumber, and Points (corner coordinates). If results are present but unexpected, first check BarcodeType against the expected format and verify the PageNumber.
Input
A Code128 barcode encoding an invoice number, read with ExpectBarcodeTypes set to Code128 and QRCode, and ReadingSpeed.Detailed for thorough scanning.
using IronBarCode;string filePath = "scanned-invoice.png";// Configure the reader to narrow the search to specific symbologies and use// a thorough scan pass — narrows false positives and improves decode accuracyvar options = new BarcodeReaderOptions{ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formatsSpeed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged imagesExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match};BarcodeResults results = BarcodeReader.Read(filePath, options);// An empty result is not an exception — it means no barcode matched the configured optionsif (results == null || results.Count == 0){ // Log the configured options alongside the warning so the cause is immediately actionableConsole.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");Console.Error.WriteLine($" Speed: {options.Speed}");Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");}else{ foreach (BarcodeResult result in results) { // Points contains the four corner coordinates of the barcode in the image; // use the first corner as a representative position indicator string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";Console.WriteLine($"[{result.BarcodeType}] {result.Value} " + $"(Page: {result.PageNumber}, Position: {pos})"); }}
using IronBarCode;
string filePath = "scanned-invoice.png";
// Configure the reader to narrow the search to specific symbologies and use
// a thorough scan pass — narrows false positives and improves decode accuracy
var options = new BarcodeReaderOptions
{
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit scan to known formats
Speed = ReadingSpeed.Detailed, // slower but more thorough — use ExtremeDetail for damaged images
ExpectMultipleBarcodes = true // scan the full image rather than stopping at the first match
};
BarcodeResults results = BarcodeReader.Read(filePath, options);
// An empty result is not an exception — it means no barcode matched the configured options
if (results == null || results.Count == 0)
{
// Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}");
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}");
Console.Error.WriteLine($" Speed: {options.Speed}");
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes");
}
else
{
foreach (BarcodeResult result in results)
{
// Points contains the four corner coordinates of the barcode in the image;
// use the first corner as a representative position indicator
string pos = result.Points.Length > 0 ? $"{result.Points[0].X:F0},{result.Points[0].Y:F0}" : "N/A";
Console.WriteLine($"[{result.BarcodeType}] {result.Value} "
+ $"(Page: {result.PageNumber}, Position: {pos})");
}
}
ImportsIronBarCodeDim filePath AsString = "scanned-invoice.png"' Configure the reader to narrow the search to specific symbologies and use' a thorough scan pass — narrows false positives and improves decode accuracyDim options As New BarcodeReaderOptionsWith { .ExpectBarcodeTypes = BarcodeEncoding.Code128OrBarcodeEncoding.QRCode, ' limit scan to known formats .Speed = ReadingSpeed.Detailed, ' slower but more thorough — use ExtremeDetail for damaged images .ExpectMultipleBarcodes = True ' scan the full image rather than stopping at the first match}Dim results AsBarcodeResults = BarcodeReader.Read(filePath, options)' An empty result is not an exception — it means no barcode matched the configured optionsIf results Is NothingOrElse results.Count = 0 Then ' Log the configured options alongside the warning so the cause is immediately actionableConsole.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}")Console.Error.WriteLine($" Speed: {options.Speed}")Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")Else For Each result AsBarcodeResultIn results ' Points contains the four corner coordinates of the barcode in the image; ' use the first corner as a representative position indicator Dim pos AsString = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")Console.WriteLine($"[{result.BarcodeType}] {result.Value} " & $"(Page: {result.PageNumber}, Position: {pos})") NextEnd If
Imports IronBarCode
Dim filePath As String = "scanned-invoice.png"
' Configure the reader to narrow the search to specific symbologies and use
' a thorough scan pass — narrows false positives and improves decode accuracy
Dim options As New BarcodeReaderOptions With {
.ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit scan to known formats
.Speed = ReadingSpeed.Detailed, ' slower but more thorough — use ExtremeDetail for damaged images
.ExpectMultipleBarcodes = True ' scan the full image rather than stopping at the first match
}
Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
' An empty result is not an exception — it means no barcode matched the configured options
If results Is Nothing OrElse results.Count = 0 Then
' Log the configured options alongside the warning so the cause is immediately actionable
Console.Error.WriteLine($"[WARN] No barcodes found in: {filePath}")
Console.Error.WriteLine($" ExpectedTypes: {options.ExpectBarcodeTypes}")
Console.Error.WriteLine($" Speed: {options.Speed}")
Console.Error.WriteLine($" Action: Retry with ReadingSpeed.ExtremeDetail or broaden ExpectBarcodeTypes")
Else
For Each result As BarcodeResult In results
' Points contains the four corner coordinates of the barcode in the image;
' use the first corner as a representative position indicator
Dim pos As String = If(result.Points.Length > 0, $"{result.Points(0).X:F0},{result.Points(0).Y:F0}", "N/A")
Console.WriteLine($"[{result.BarcodeType}] {result.Value} " &
$"(Page: {result.PageNumber}, Position: {pos})")
Next
End If
Output
Please note: When ExpectBarcodeTypes matches the barcode in the image, the read returns the type, value, page number, and position.
If ExpectBarcodeTypes does not include the actual symbology, the read returns an empty result. The [WARN] block logs the configured types, reading speed, and a suggested next action.
Two common patterns emerge during diagnostics. Empty results with a narrow ExpectBarcodeTypes setting often mean the barcode uses a different symbology; expanding to BarcodeEncoding.All can confirm this. Unexpected decode results usually point to poor image quality.
Applying image filters and retrying with a slower reading speed often resolves these issues. You can also toggle the RemoveFalsePositive option to eliminate phantom reads from noisy backgrounds.
How Do I Enable Verbose Logging for Barcode Operations?
IronBarcode exposes a built-in logging API through IronSoftware.Logger. Set the logging mode and file path before any barcode operations to capture internal diagnostic output from the read and write pipelines.
Input
A Code128 barcode TIFF image used as the read target while verbose logging is active.
using IronBarCode;// Enable IronBarcode's built-in logging — set BEFORE any read/write calls// LoggingModes.All writes both debug output and file-level diagnosticsIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory// All subsequent operations will write internal processing steps to the log file:// image pre-processing stages, format detection attempts, and native interop callsvar options = new BarcodeReaderOptions{Speed = ReadingSpeed.Detailed,ExpectBarcodeTypes = BarcodeEncoding.All// scan for every supported symbology};BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
using IronBarCode;
// Enable IronBarcode's built-in logging — set BEFORE any read/write calls
// LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log"; // path is relative to the working directory
// All subsequent operations will write internal processing steps to the log file:
// image pre-processing stages, format detection attempts, and native interop calls
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Detailed,
ExpectBarcodeTypes = BarcodeEncoding.All // scan for every supported symbology
};
BarcodeResults results = BarcodeReader.Read("problem-scan.tiff", options);
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.");
ImportsIronBarCode' Enable IronBarcode's built-in logging — set BEFORE any read/write calls' LoggingModes.All writes both debug output and file-level diagnosticsIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.AllIronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory' All subsequent operations will write internal processing steps to the log file:' image pre-processing stages, format detection attempts, and native interop callsDim options As New BarcodeReaderOptionsWith { .Speed = ReadingSpeed.Detailed, .ExpectBarcodeTypes = BarcodeEncoding.All' scan for every supported symbology}Dim results AsBarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
Imports IronBarCode
' Enable IronBarcode's built-in logging — set BEFORE any read/write calls
' LoggingModes.All writes both debug output and file-level diagnostics
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "ironbarcode-debug.log" ' path is relative to the working directory
' All subsequent operations will write internal processing steps to the log file:
' image pre-processing stages, format detection attempts, and native interop calls
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Detailed,
.ExpectBarcodeTypes = BarcodeEncoding.All ' scan for every supported symbology
}
Dim results As BarcodeResults = BarcodeReader.Read("problem-scan.tiff", options)
Console.WriteLine($"Read complete. Results: {results.Count}. See ironbarcode-debug.log for details.")
LoggingModes.All captures both debug output and file-level logging. The log file records internal processing steps, such as image pre-processing stages, format detection attempts, and native interop calls, which are not visible through the public API.
For production pipelines using a structured logging framework (Serilog, NLog, Microsoft.Extensions.Logging), wrapping IronBarcode operations in a middleware layer adds structured JSON entries alongside the built-in log file. The built-in logger writes plain-text diagnostics useful for support escalation; the structured wrapper provides queryable fields for the observability stack.
using IronBarCode;using System.Diagnostics;// Lightweight wrapper that adds structured JSON observability to every read call.// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.BarcodeResultsReadWithDiagnostics(string filePath, BarcodeReaderOptions options){ var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included try { BarcodeResults results = BarcodeReader.Read(filePath, options); sw.Stop(); // Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatchConsole.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\"," + $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}"); return results; } catch (Exception ex) { sw.Stop(); // Emit a structured error entry to stderr with exception type, message, and elapsed timeConsole.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\"," + $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\"," + $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}"); throw; // rethrow so the caller's catch blocks still handle the exception normally }}
using IronBarCode;
using System.Diagnostics;
// Lightweight wrapper that adds structured JSON observability to every read call.
// Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
BarcodeResults ReadWithDiagnostics(string filePath, BarcodeReaderOptions options)
{
var sw = Stopwatch.StartNew(); // start timing before the read so setup overhead is included
try
{
BarcodeResults results = BarcodeReader.Read(filePath, options);
sw.Stop();
// Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
Console.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"ok\","
+ $"\"count\":{results.Count},\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
return results;
}
catch (Exception ex)
{
sw.Stop();
// Emit a structured error entry to stderr with exception type, message, and elapsed time
Console.Error.WriteLine($"{{\"file\":\"{filePath}\",\"status\":\"error\","
+ $"\"exception\":\"{ex.GetType().Name}\",\"message\":\"{ex.Message}\","
+ $"\"elapsed_ms\":{sw.ElapsedMilliseconds}}}");
throw; // rethrow so the caller's catch blocks still handle the exception normally
}
}
ImportsIronBarCodeImportsSystem.Diagnostics' Lightweight wrapper that adds structured JSON observability to every read call.' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.FunctionReadWithDiagnostics(filePath AsString, options AsBarcodeReaderOptions) AsBarcodeResults Dim sw AsStopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is includedTry Dim results AsBarcodeResults = BarcodeReader.Read(filePath, options) sw.Stop() ' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatchConsole.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}") Return resultsCatch ex AsException sw.Stop() ' Emit a structured error entry to stderr with exception type, message, and elapsed timeConsole.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")Throw' rethrow so the caller's catch blocks still handle the exception normallyEndTryEnd Function
Imports IronBarCode
Imports System.Diagnostics
' Lightweight wrapper that adds structured JSON observability to every read call.
' Call this in place of BarcodeReader.Read wherever elapsed-time and status logging is needed.
Function ReadWithDiagnostics(filePath As String, options As BarcodeReaderOptions) As BarcodeResults
Dim sw As Stopwatch = Stopwatch.StartNew() ' start timing before the read so setup overhead is included
Try
Dim results As BarcodeResults = BarcodeReader.Read(filePath, options)
sw.Stop()
' Emit a structured success entry to stdout — pipe to Fluentd, Datadog, or CloudWatch
Console.WriteLine($"{{""file"":""{filePath}"",""status"":""ok"",""count"":{results.Count},""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
Return results
Catch ex As Exception
sw.Stop()
' Emit a structured error entry to stderr with exception type, message, and elapsed time
Console.Error.WriteLine($"{{""file"":""{filePath}"",""status"":""error"",""exception"":""{ex.GetType().Name}"",""message"":""{ex.Message}"",""elapsed_ms"":{sw.ElapsedMilliseconds}}}")
Throw ' rethrow so the caller's catch blocks still handle the exception normally
End Try
End Function
The structured output integrates directly with log aggregation tools. Pipe stdout to Fluentd, Datadog, or CloudWatch in a containerized deployment. The elapsed-time field highlights performance regressions before they become SLA violations.
Output
How Do I Debug Batch Barcode Processing?
Process multiple files by isolating each read in its own try-catch block, recording outcomes for each file, and generating an aggregate summary. The pipeline continues through failures instead of stopping at the first error.
Input
Four of the five Code128 barcode images from the scans/ batch directory. The fifth file (scan-05-broken.png) contains invalid bytes to trigger a file exception.
Batch 1 - Scan 1
Batch 1 - Scan 2
Batch 1 - Scan 3
Batch 1 - Scan 4
using IronBarCode;using IronBarCode.Exceptions;using System.Diagnostics;// Enable built-in logging for the entire batch run so internal processing steps// are captured in the log file alongside the per-file console outputIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;IronSoftware.Logger.LogFilePath = "batch-run.log";// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectoriesstring[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);var options = new BarcodeReaderOptions{Speed = ReadingSpeed.Balanced, // balances throughput vs accuracyExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formatsExpectMultipleBarcodes = true // scan each file fully};// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)int successCount = 0;int failCount = 0;int emptyCount = 0;var errors = new List<(stringFile, stringError)>(); // per-file error context for root cause analysisvar sw = Stopwatch.StartNew();foreach (string file in files){ try { BarcodeResults results = BarcodeReader.Read(file, options); // Empty result is not an exception — the file was read but contained no matching barcode if (results == null || results.Count == 0) { emptyCount++; errors.Add((file, "No barcodes detected")); // record so caller can adjust options continue; } foreach (BarcodeResult result in results) {Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}"); } successCount++; } catch (IronBarCodePdfPasswordException) { // PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover failCount++; errors.Add((file, "Password-protected PDF")); } catch (IronBarCodeFileException ex) { // File is corrupted, locked, or in an unsupported image format failCount++; errors.Add((file, $"File error: {ex.Message}")); } catch (FileNotFoundException ex) { // File was in the directory listing but deleted before the read completed (race condition) failCount++; errors.Add((file, $"File not found: {ex.Message}")); } catch (IronBarCodeException ex) { // Catch-all for any other IronBarcode-specific errors not handled above failCount++; errors.Add((file, $"{ex.GetType().Name}: {ex.Message}")); } catch (Exception ex) { // Unexpected non-IronBarcode error — log the full type for investigation failCount++; errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}")); }}sw.Stop();// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit codeConsole.WriteLine("\n--- Batch Summary ---");Console.WriteLine($"Total files: {files.Length}");Console.WriteLine($"Success: {successCount}");Console.WriteLine($"Empty reads: {emptyCount}");Console.WriteLine($"Failures: {failCount}");Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");if (errors.Any()){Console.WriteLine("\n--- Error Details ---"); foreach (var (errorFile, errorMsg) in errors) {Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}"); }}
using IronBarCode;
using IronBarCode.Exceptions;
using System.Diagnostics;
// Enable built-in logging for the entire batch run so internal processing steps
// are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All;
IronSoftware.Logger.LogFilePath = "batch-run.log";
// Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
string[] files = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly);
var options = new BarcodeReaderOptions
{
Speed = ReadingSpeed.Balanced, // balances throughput vs accuracy
ExpectBarcodeTypes = BarcodeEncoding.Code128 | BarcodeEncoding.QRCode, // limit to known formats
ExpectMultipleBarcodes = true // scan each file fully
};
// Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
int successCount = 0;
int failCount = 0;
int emptyCount = 0;
var errors = new List<(string File, string Error)>(); // per-file error context for root cause analysis
var sw = Stopwatch.StartNew();
foreach (string file in files)
{
try
{
BarcodeResults results = BarcodeReader.Read(file, options);
// Empty result is not an exception — the file was read but contained no matching barcode
if (results == null || results.Count == 0)
{
emptyCount++;
errors.Add((file, "No barcodes detected")); // record so caller can adjust options
continue;
}
foreach (BarcodeResult result in results)
{
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}");
}
successCount++;
}
catch (IronBarCodePdfPasswordException)
{
// PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount++;
errors.Add((file, "Password-protected PDF"));
}
catch (IronBarCodeFileException ex)
{
// File is corrupted, locked, or in an unsupported image format
failCount++;
errors.Add((file, $"File error: {ex.Message}"));
}
catch (FileNotFoundException ex)
{
// File was in the directory listing but deleted before the read completed (race condition)
failCount++;
errors.Add((file, $"File not found: {ex.Message}"));
}
catch (IronBarCodeException ex)
{
// Catch-all for any other IronBarcode-specific errors not handled above
failCount++;
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"));
}
catch (Exception ex)
{
// Unexpected non-IronBarcode error — log the full type for investigation
failCount++;
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"));
}
}
sw.Stop();
// Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine("\n--- Batch Summary ---");
Console.WriteLine($"Total files: {files.Length}");
Console.WriteLine($"Success: {successCount}");
Console.WriteLine($"Empty reads: {emptyCount}");
Console.WriteLine($"Failures: {failCount}");
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s");
if (errors.Any())
{
Console.WriteLine("\n--- Error Details ---");
foreach (var (errorFile, errorMsg) in errors)
{
Console.Error.WriteLine($" {Path.GetFileName(errorFile)}: {errorMsg}");
}
}
ImportsIronBarCodeImportsIronBarCode.ExceptionsImportsSystem.Diagnostics' Enable built-in logging for the entire batch run so internal processing steps' are captured in the log file alongside the per-file console outputIronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.AllIronSoftware.Logger.LogFilePath = "batch-run.log"' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectoriesDim files AsString() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)Dim options As New BarcodeReaderOptionsWith { .Speed = ReadingSpeed.Balanced, ' balances throughput vs accuracy .ExpectBarcodeTypes = BarcodeEncoding.Code128OrBarcodeEncoding.QRCode, ' limit to known formats .ExpectMultipleBarcodes = True ' scan each file fully}' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)Dim successCount AsInteger = 0Dim failCount AsInteger = 0Dim emptyCount AsInteger = 0Dim errors As New List(Of (FileAsString, ErrorAsString))() ' per-file error context for root cause analysisDim sw AsStopwatch = Stopwatch.StartNew()For Each file AsStringIn filesTry Dim results AsBarcodeResults = BarcodeReader.Read(file, options) ' Empty result is not an exception — the file was read but contained no matching barcode If results Is NothingOrElse results.Count = 0 Then emptyCount += 1 errors.Add((file, "No barcodes detected")) ' record so caller can adjust options Continue For End If For Each result AsBarcodeResultIn resultsConsole.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}") Next successCount += 1Catch ex AsIronBarCodePdfPasswordException ' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover failCount += 1 errors.Add((file, "Password-protected PDF"))Catch ex AsIronBarCodeFileException ' File is corrupted, locked, or in an unsupported image format failCount += 1 errors.Add((file, $"File error: {ex.Message}"))Catch ex AsFileNotFoundException ' File was in the directory listing but deleted before the read completed (race condition) failCount += 1 errors.Add((file, $"File not found: {ex.Message}"))Catch ex AsIronBarCodeException ' Catch-all for any other IronBarcode-specific errors not handled above failCount += 1 errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))Catch ex AsException ' Unexpected non-IronBarcode error — log the full type for investigation failCount += 1 errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))EndTryNextsw.Stop()' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit codeConsole.WriteLine(vbCrLf & "--- Batch Summary ---")Console.WriteLine($"Total files: {files.Length}")Console.WriteLine($"Success: {successCount}")Console.WriteLine($"Empty reads: {emptyCount}")Console.WriteLine($"Failures: {failCount}")Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s")If errors.Any() ThenConsole.WriteLine(vbCrLf & "--- Error Details ---") For Each errorDetail In errorsConsole.Error.WriteLine($" {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}") NextEnd If
Imports IronBarCode
Imports IronBarCode.Exceptions
Imports System.Diagnostics
' Enable built-in logging for the entire batch run so internal processing steps
' are captured in the log file alongside the per-file console output
IronSoftware.Logger.LoggingMode = IronSoftware.Logger.LoggingModes.All
IronSoftware.Logger.LogFilePath = "batch-run.log"
' Collect all files in the directory — SearchOption.TopDirectoryOnly skips subdirectories
Dim files As String() = Directory.GetFiles("scans/", "*.*", SearchOption.TopDirectoryOnly)
Dim options As New BarcodeReaderOptions With {
.Speed = ReadingSpeed.Balanced, ' balances throughput vs accuracy
.ExpectBarcodeTypes = BarcodeEncoding.Code128 Or BarcodeEncoding.QRCode, ' limit to known formats
.ExpectMultipleBarcodes = True ' scan each file fully
}
' Three outcome counters: success (decoded), empty (read OK but no barcode found), fail (exception)
Dim successCount As Integer = 0
Dim failCount As Integer = 0
Dim emptyCount As Integer = 0
Dim errors As New List(Of (File As String, Error As String))() ' per-file error context for root cause analysis
Dim sw As Stopwatch = Stopwatch.StartNew()
For Each file As String In files
Try
Dim results As BarcodeResults = BarcodeReader.Read(file, options)
' Empty result is not an exception — the file was read but contained no matching barcode
If results Is Nothing OrElse results.Count = 0 Then
emptyCount += 1
errors.Add((file, "No barcodes detected")) ' record so caller can adjust options
Continue For
End If
For Each result As BarcodeResult In results
Console.WriteLine($"{Path.GetFileName(file)} | {result.BarcodeType} | {result.Value}")
Next
successCount += 1
Catch ex As IronBarCodePdfPasswordException
' PDF is password-protected — supply password via PdfBarcodeReaderOptions to recover
failCount += 1
errors.Add((file, "Password-protected PDF"))
Catch ex As IronBarCodeFileException
' File is corrupted, locked, or in an unsupported image format
failCount += 1
errors.Add((file, $"File error: {ex.Message}"))
Catch ex As FileNotFoundException
' File was in the directory listing but deleted before the read completed (race condition)
failCount += 1
errors.Add((file, $"File not found: {ex.Message}"))
Catch ex As IronBarCodeException
' Catch-all for any other IronBarcode-specific errors not handled above
failCount += 1
errors.Add((file, $"{ex.GetType().Name}: {ex.Message}"))
Catch ex As Exception
' Unexpected non-IronBarcode error — log the full type for investigation
failCount += 1
errors.Add((file, $"Unexpected: {ex.GetType().Name}: {ex.Message}"))
End Try
Next
sw.Stop()
' Summary report — parse failCount > 0 in CI/CD to set a non-zero exit code
Console.WriteLine(vbCrLf & "--- Batch Summary ---")
Console.WriteLine($"Total files: {files.Length}")
Console.WriteLine($"Success: {successCount}")
Console.WriteLine($"Empty reads: {emptyCount}")
Console.WriteLine($"Failures: {failCount}")
Console.WriteLine($"Elapsed: {sw.Elapsed.TotalSeconds:F1}s")
If errors.Any() Then
Console.WriteLine(vbCrLf & "--- Error Details ---")
For Each errorDetail In errors
Console.Error.WriteLine($" {Path.GetFileName(errorDetail.File)}: {errorDetail.Error}")
Next
End If
Output
During execution, the console outputs one line for each decoded barcode, followed by a summary with file count, successes, empty reads, failures, and elapsed time. Errors are listed with their corresponding file names and reasons for failure.
The process distinguishes three outcome categories: success (barcodes found and decoded), empty (file read but no barcodes detected), and failure (exception thrown). This distinction matters because empty reads and failures require different responses. Empty reads may need broader format settings, while failures often indicate infrastructure issues such as missing files, locked resources, or missing native dependencies.
The error list maintains per-file context to support root cause analysis. In a CI/CD pipeline, parse this output to set exit codes (zero for complete success and non-zero when failCount is greater than zero) or forward error details to an alerting system.
For higher throughput, enable parallel processing by setting Multithreaded to true and adjusting MaxParallelThreads to match available CPU cores. Maintain per-file isolation by wrapping the parallel iteration in Parallel.ForEach and using a thread-safe collection for the error list.
How can I handle barcode errors in C# using IronBarcode?
You can handle barcode errors in C# using IronBarcode by utilizing its typed exception hierarchy within the IronBarCode.Exceptions namespace. This allows you to catch specific exceptions related to file errors, PDF passwords, encoding issues, and more. Implementing structured logging and using the BarcodeResult properties helps to diagnose and isolate issues efficiently.
What are some common exceptions thrown by IronBarcode?
IronBarcode can throw various exceptions such as IronBarCodeFileException for file-related issues, IronBarCodePdfPasswordException for password-protected PDFs, and IronBarCodeEncodingException for encoding failures. Each exception type provides detailed diagnostic information to help resolve specific errors encountered during barcode processing.
How do I enable logging for diagnostics in IronBarcode?
To enable logging for diagnostics in IronBarcode, set the logging mode and file path using IronSoftware.Logger before any barcode operations. This captures internal processing steps and helps track issues by writing logs to the specified file.
What should I do if a barcode read operation returns zero results in IronBarcode?
If a barcode read operation returns zero results in IronBarcode, it indicates that no barcode matched the configured options. Inspect your input parameters and options, such as ExpectBarcodeTypes and ReadingSpeed, and consider broadening the symbology expectations or adjusting the reading speed for more thorough scanning.
Can IronBarcode handle exceptions for missing native dependencies?
Yes, IronBarcode handles exceptions for missing native dependencies through the IronBarCodeNativeException. You can filter these exceptions to identify missing DLLs or platform dependencies, which is particularly useful in Docker environments.
How can I debug batch processing of barcodes with IronBarcode?
For debugging batch barcode processing in IronBarcode, isolate each read operation in its own try-catch block and capture errors per file. This approach ensures that the batch operation continues through failures and generates a summary that includes successes, failures, and empty results.
How can I catch and interpret exceptions effectively in IronBarcode?
Catch and interpret exceptions in IronBarcode by ordering your try-catch blocks from specific to general. Start with actionable exceptions like file errors or PDF password issues and end with the base IronBarCodeException to ensure comprehensive error handling.
What properties of BarcodeResult can be used for post-mortem analysis?
The BarcodeResult object in IronBarcode provides properties like BarcodeType, Value, PageNumber, and Points (coordinates) for post-mortem analysis. These properties help in understanding unexpected results by checking the actual versus expected barcode type and verifying the page number.
In IronBarcode, how can I prevent false positives during barcode reads?
To prevent false positives during barcode reads in IronBarcode, you can use image filters to enhance image quality and the RemoveFalsePositive option. Additionally, adjusting reading speed and ExpectBarcodeTypes can minimize errors from noisy backgrounds.
How does IronBarcode handle errors from encrypted PDFs?
IronBarcode handles errors from encrypted PDFs using the IronBarCodePdfPasswordException. To process such files, supply the password using PdfBarcodeReaderOptions or log and skip them for non-disruptive barcode processing.
Curtis Chau holds a Bachelor’s degree in Computer Science (Carleton University) and specializes in front-end development with expertise in Node.js, TypeScript, JavaScript, and React. Passionate about crafting intuitive and aesthetically pleasing user interfaces, Curtis enjoys working with modern frameworks and creating well-structured, visually appealing manuals.