or run

tessl search
Log in

Version

Workspace
tessl
Visibility
Public
Created
Last updated

docs

index.md
tile.json

tessl/github-zxing-cpp--zxing-cpp

tessl install tessl/github-zxing-cpp--zxing-cpp@2.3.0

Open-source, multi-format linear/matrix barcode image processing library implemented in C++

errors.mddocs/reference/

Error Handling

ZXing-C++ uses a value-based error handling approach through the Error class. Instead of throwing exceptions for barcode decoding failures, errors are returned as part of the Barcode result.

Error Class

class Error {
public:
    enum class Type : uint8_t {
        None        = 0,  // No error
        Format      = 1,  // Format/decoding error
        Checksum    = 2,  // Checksum validation failed
        Unsupported = 3   // Unsupported feature
    };

    // Constructors
    Error();  // Default no-error state
    Error(Type type, std::string msg = {});
    Error(const char* file, short line, Type type, std::string msg = {});

    // Accessors
    Type type() const;
    const std::string& msg() const;
    std::string location() const;

    // Conversion
    explicit operator bool() const;  // True if error exists

    // Comparison
    bool operator==(const Error& other) const;
    bool operator!=(const Error& other) const;

    // Static convenience constants
    static constexpr auto Format = Type::Format;
    static constexpr auto Checksum = Type::Checksum;
    static constexpr auto Unsupported = Type::Unsupported;
};

// Utility function
std::string ToString(const Error& e);

Error Types

None

No error occurred - the operation was successful:

auto barcode = ZXing::ReadBarcode(image);

if (barcode.error().type() == ZXing::Error::Type::None) {
    std::cout << "Success: " << barcode.text() << "\n";
}

// More concise - check validity
if (barcode.isValid()) {
    std::cout << "Success: " << barcode.text() << "\n";
}

Format

Format or decoding error - the barcode was detected but could not be decoded:

if (barcode.error().type() == ZXing::Error::Type::Format) {
    std::cerr << "Format error: " << barcode.error().msg() << "\n";
}

// Or using static constant
if (barcode.error().type() == ZXing::Error::Format) {
    std::cerr << "Decoding failed\n";
}

Common format errors:

  • Malformed barcode structure
  • Invalid data encoding
  • Corrupted bit pattern
  • Incomplete barcode

Checksum

Checksum validation failed - the barcode was decoded but data integrity check failed:

if (barcode.error().type() == ZXing::Error::Type::Checksum) {
    std::cerr << "Checksum error: " << barcode.error().msg() << "\n";
}

// Or using static constant
if (barcode.error().type() == ZXing::Error::Checksum) {
    std::cerr << "Data integrity check failed\n";
}

Checksum errors indicate:

  • Data corruption during printing or scanning
  • Poor image quality affecting bits
  • Partial obstruction of barcode
  • Still recoverable in some cases if returnErrors is enabled

Unsupported

Unsupported feature encountered:

if (barcode.error().type() == ZXing::Error::Type::Unsupported) {
    std::cerr << "Unsupported: " << barcode.error().msg() << "\n";
}

Examples:

  • Unsupported barcode variant
  • Unsupported character encoding
  • Feature not compiled in

Checking for Errors

Using isValid()

The simplest way to check for errors:

auto barcode = ZXing::ReadBarcode(image);

if (barcode.isValid()) {
    // No error - safe to use barcode
    std::cout << barcode.text() << "\n";
} else {
    // Error occurred
    std::cerr << "Error: " << barcode.error().msg() << "\n";
}

Using operator bool()

The Error class converts to bool:

const ZXing::Error& error = barcode.error();

if (error) {
    // Error exists
    std::cerr << "Error type: " << (int)error.type() << "\n";
    std::cerr << "Message: " << error.msg() << "\n";
} else {
    // No error
    std::cout << "Success\n";
}

Checking Error Type

switch (barcode.error().type()) {
    case ZXing::Error::Type::None:
        std::cout << "Success: " << barcode.text() << "\n";
        break;

    case ZXing::Error::Type::Format:
        std::cerr << "Decoding failed: " << barcode.error().msg() << "\n";
        break;

    case ZXing::Error::Type::Checksum:
        std::cerr << "Checksum failed: " << barcode.error().msg() << "\n";
        // Might still be usable depending on requirements
        break;

    case ZXing::Error::Type::Unsupported:
        std::cerr << "Unsupported: " << barcode.error().msg() << "\n";
        break;
}

Error Messages

Error objects include descriptive messages:

const ZXing::Error& error = barcode.error();

if (error) {
    std::string message = error.msg();
    std::cout << "Error message: " << message << "\n";

    // Convert entire error to string
    std::string fullError = ZXing::ToString(error);
    std::cout << "Full error: " << fullError << "\n";
}

Messages typically include:

  • Description of what went wrong
  • Specific detail about the failure point
  • Hints for resolution when applicable

Error Location

Errors can include source location information for debugging:

const ZXing::Error& error = barcode.error();

if (error) {
    std::string location = error.location();
    if (!location.empty()) {
        std::cout << "Error at: " << location << "\n";
    }
}

Location format: "file:line"

Returning Errors with Results

By default, ReadBarcode() and ReadBarcodes() do not return barcodes with errors. Configure ReaderOptions to get partial results:

// Return barcodes even if they have errors
auto options = ZXing::ReaderOptions()
    .setReturnErrors(true);

auto barcodes = ZXing::ReadBarcodes(image, options);

for (const auto& bc : barcodes) {
    if (bc.isValid()) {
        std::cout << "Valid: " << bc.text() << "\n";
    } else {
        // Error barcode returned
        std::cerr << "Error: " << ZXing::ToString(bc.error()) << "\n";

        // Might still have partial data
        if (bc.error().type() == ZXing::Error::Type::Checksum) {
            // Checksum failed but data was decoded
            std::cout << "Unchecked content: " << bc.text() << "\n";
        }
    }
}

Use cases for returnErrors:

  • Debug barcode quality issues
  • Extract partial data when checksum fails
  • Analyze why detection is failing
  • Implement custom error handling

Creating Errors

Error creation is typically internal, but you can create errors for testing or extension:

// Create error with type and message
ZXing::Error err1(ZXing::Error::Type::Format, "Invalid barcode structure");

// Create error with location information
ZXing::Error err2(__FILE__, __LINE__, ZXing::Error::Type::Checksum,
                  "Checksum validation failed");

// No-error state
ZXing::Error noError;  // Type::None

Error Creation Macros

For internal use, macros are provided to automatically capture location:

// These macros are for library implementation, not public API
// FormatError("message")
// ChecksumError("message")
// UnsupportedError("message")

Error Comparison

ZXing::Error err1(ZXing::Error::Type::Format, "Error 1");
ZXing::Error err2(ZXing::Error::Type::Format, "Error 1");
ZXing::Error err3(ZXing::Error::Type::Checksum, "Error 2");

if (err1 == err2) {
    std::cout << "Errors are equal\n";  // True - same type and message
}

if (err1 != err3) {
    std::cout << "Errors are different\n";  // True - different types
}

Comparison considers:

  • Error type
  • Error message
  • Location is NOT compared

No Exceptions

ZXing-C++ does not throw exceptions for normal barcode reading failures:

// This never throws for "no barcode found" or decoding failures
auto barcode = ZXing::ReadBarcode(image);

// Always safe to call
if (!barcode.isValid()) {
    // Handle error gracefully
}

Exceptions may be thrown for:

  • Invalid API usage (e.g., invalid format string in BarcodeFormatsFromString)
  • Memory allocation failures (std::bad_alloc)
  • Internal logic errors (should not happen in release builds)

Best Practices

Always Check Validity

auto barcode = ZXing::ReadBarcode(image);

// Always check before using
if (barcode.isValid()) {
    processBarcode(barcode);
}

Provide User Feedback

auto barcode = ZXing::ReadBarcode(image);

if (!barcode.isValid()) {
    switch (barcode.error().type()) {
        case ZXing::Error::Format:
            showMessage("Could not decode barcode. Please ensure it's not damaged.");
            break;
        case ZXing::Error::Checksum:
            showMessage("Barcode appears corrupted. Please try again.");
            break;
        case ZXing::Error::Unsupported:
            showMessage("This barcode format is not supported.");
            break;
        default:
            showMessage("No barcode detected in image.");
            break;
    }
}

Log Errors for Debugging

void logBarcode(const ZXing::Barcode& barcode) {
    if (barcode.isValid()) {
        LOG_INFO << "Decoded: " << ZXing::ToString(barcode.format())
                 << " - " << barcode.text();
    } else {
        LOG_ERROR << "Failed to decode barcode: "
                  << "Type=" << (int)barcode.error().type()
                  << " Message=" << barcode.error().msg()
                  << " Location=" << barcode.error().location();
    }
}

Handle Checksum Errors Appropriately

Checksum errors mean data was decoded but may be corrupted:

if (barcode.error().type() == ZXing::Error::Type::Checksum) {
    // Data is available but unverified
    std::string data = barcode.text();

    // Decide based on application requirements
    if (isLowRiskOperation()) {
        // Use data anyway
        processData(data);
        warnUser("Checksum failed - data may be incorrect");
    } else {
        // Reject data
        showError("Data integrity check failed - please scan again");
    }
}

Working with Multiple Results

auto barcodes = ZXing::ReadBarcodes(image);

int validCount = 0;
int errorCount = 0;

for (const auto& bc : barcodes) {
    if (bc.isValid()) {
        ++validCount;
        processBarcode(bc);
    } else {
        ++errorCount;
        logError(bc.error());
    }
}

std::cout << "Valid: " << validCount << ", Errors: " << errorCount << "\n";

Related

  • Barcode Results - Barcode class and result handling
  • Barcode Reading - Reading operations that return errors
  • Reader Options - Configuring error behavior