Skip to content

Error Handling

compressionz uses a unified error type across all operations for consistent error handling.

pub const Error = error{
InvalidData,
ChecksumMismatch,
OutputTooSmall,
OutputTooLarge,
UnexpectedEof,
UnsupportedFeature,
OutOfMemory,
DictionaryMismatch,
InvalidParameter,
};

The input data is corrupted, malformed, or not compressed with the specified codec.

Common causes:

  • Data was modified after compression
  • Wrong codec specified for decompression
  • Truncated compressed data
  • Random/uncompressed data passed to decompress

Example:

const result = cz.decompress(.zstd, random_data, allocator) catch |err| {
if (err == error.InvalidData) {
std.debug.print("Data is not valid Zstd compressed data\n", .{});
return;
}
return err;
};

Solutions:

  1. Verify you’re using the correct codec
  2. Check data wasn’t corrupted in transit/storage
  3. Use auto-detection: cz.Codec.detect(data)

Built-in checksum verification failed. Data integrity compromised.

Common causes:

  • Data corruption during storage or transmission
  • Partial/incomplete data
  • Hardware errors (disk, memory)

Example:

const result = cz.decompress(.lz4, data, allocator) catch |err| {
if (err == error.ChecksumMismatch) {
std.debug.print("Data corrupted! Checksum verification failed.\n", .{});
// Request retransmission, restore from backup, etc.
return error.DataCorruption;
}
return err;
};

Solutions:

  1. Re-fetch or restore data from source
  2. Check storage/network for errors
  3. Use checksums at application level too

Note: Only occurs for codecs with checksums: .lz4, .gzip, .zlib, .zstd


Buffer provided to compressInto or decompressInto is too small.

Common causes:

  • Pre-allocated buffer undersized
  • Incorrect size calculation

Example:

var small_buffer: [100]u8 = undefined;
const result = cz.compressInto(.lz4, large_data, &small_buffer, .{}) catch |err| {
if (err == error.OutputTooSmall) {
// Allocate larger buffer
const size = cz.maxCompressedSize(.lz4, large_data.len);
const buffer = try allocator.alloc(u8, size);
return cz.compressInto(.lz4, large_data, buffer, .{});
}
return err;
};

Solutions:

  1. Use maxCompressedSize() for compression buffers
  2. Use known original size for decompression buffers
  3. Fall back to allocating API

Decompressed size exceeds max_output_size limit.

Common causes:

  • Decompression bomb (malicious data)
  • Unexpectedly large legitimate data
  • Limit set too low

Example:

const result = cz.decompressWithOptions(.gzip, untrusted_data, allocator, .{
.max_output_size = 10 * 1024 * 1024, // 10 MB limit
}) catch |err| {
if (err == error.OutputTooLarge) {
std.debug.print("Decompressed size exceeds 10 MB limit\n", .{});
return error.SuspiciousInput;
}
return err;
};

Solutions:

  1. Increase limit if data is trusted
  2. Reject untrusted data that exceeds limits
  3. Stream process large data instead

Compressed data ended unexpectedly. Input is truncated.

Common causes:

  • Incomplete download/transfer
  • File truncated
  • Stream closed prematurely

Example:

const result = cz.decompress(.zstd, data, allocator) catch |err| {
if (err == error.UnexpectedEof) {
std.debug.print("Compressed data is incomplete\n", .{});
return error.IncompleteData;
}
return err;
};

Solutions:

  1. Verify complete data transfer
  2. Check file size matches expected
  3. Re-download/re-fetch data

Requested feature not available for this codec.

Common causes:

  • Zero-copy with codec that doesn’t support it
  • Dictionary with codec that doesn’t support it
  • Streaming with block-only codec

Example:

// Zstd doesn't support compressInto
const result = cz.compressInto(.zstd, data, &buffer, .{}) catch |err| {
if (err == error.UnsupportedFeature) {
// Fall back to allocating version
return cz.compress(.zstd, data, allocator);
}
return err;
};

Solutions:

  1. Check codec capabilities before using features
  2. Use fallback implementations
  3. Choose a different codec
// Check before using
if (codec.supportsDictionary()) {
return cz.compressWithOptions(codec, data, allocator, .{
.dictionary = dict,
});
} else {
return cz.compress(codec, data, allocator);
}

Memory allocation failed.

Common causes:

  • System out of memory
  • Decompressed size too large for available memory
  • Allocator limits reached

Example:

const result = cz.decompress(.zstd, data, allocator) catch |err| {
if (err == error.OutOfMemory) {
std.debug.print("Insufficient memory for decompression\n", .{});
// Try streaming API or smaller chunks
return error.ResourceExhausted;
}
return err;
};

Solutions:

  1. Use streaming API for large data
  2. Process in smaller chunks
  3. Set max_output_size to limit memory use
  4. Free other memory before retry

Dictionary used for decompression doesn’t match compression dictionary.

Common causes:

  • Wrong dictionary provided
  • Dictionary version mismatch
  • Dictionary corrupted

Example:

const result = cz.decompressWithOptions(.zstd, data, allocator, .{
.dictionary = wrong_dictionary,
}) catch |err| {
if (err == error.DictionaryMismatch) {
std.debug.print("Dictionary doesn't match compressed data\n", .{});
return error.ConfigurationError;
}
return err;
};

Solutions:

  1. Verify correct dictionary is used
  2. Version dictionaries and store version with data
  3. Include dictionary ID in metadata

Invalid parameter value provided.

Common causes:

  • expected_size not provided for lz4_raw
  • Invalid option combination

Example:

// lz4_raw requires expected_size
const result = cz.decompress(.lz4_raw, data, allocator) catch |err| {
if (err == error.InvalidParameter or err == error.InvalidData) {
std.debug.print("lz4_raw requires expected_size option\n", .{});
return cz.decompressWithOptions(.lz4_raw, data, allocator, .{
.expected_size = known_size,
});
}
return err;
};

Pattern for handling all errors:

const cz = @import("compressionz");
pub fn safeDecompress(
codec: cz.Codec,
data: []const u8,
allocator: std.mem.Allocator,
max_size: usize,
) ![]u8 {
return cz.decompressWithOptions(codec, data, allocator, .{
.max_output_size = max_size,
}) catch |err| switch (err) {
error.InvalidData => {
log.err("Invalid or corrupted compressed data", .{});
return error.DataCorruption;
},
error.ChecksumMismatch => {
log.err("Checksum verification failed", .{});
return error.DataCorruption;
},
error.OutputTooLarge => {
log.warn("Decompressed size exceeds {d} byte limit", .{max_size});
return error.DataTooLarge;
},
error.UnexpectedEof => {
log.err("Compressed data truncated", .{});
return error.IncompleteData;
},
error.OutOfMemory => {
log.err("Out of memory during decompression", .{});
return error.OutOfMemory;
},
error.UnsupportedFeature => {
log.err("Codec doesn't support requested feature", .{});
return error.UnsupportedOperation;
},
else => {
log.err("Unexpected decompression error: {}", .{err});
return err;
},
};
}

ErrorRecovery Strategy
InvalidDataTry auto-detection, re-fetch data
ChecksumMismatchRe-fetch from source, restore from backup
OutputTooSmallUse larger buffer or allocating API
OutputTooLargeIncrease limit or reject
UnexpectedEofRe-fetch complete data
UnsupportedFeatureUse different API or codec
OutOfMemoryStream process, reduce limits
DictionaryMismatchUse correct dictionary
InvalidParameterFix parameters