Skip to content

A zero-dependency, header-only error handling library for C/C++ implementing robust Result types and automatic stack tracing.

License

Notifications You must be signed in to change notification settings

z-libs/zerror.h

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

zerror.h

zerror.h is a sophisticated, single-header error handling library for C and C++. It bridges the gap between low-level C programming and modern safety patterns found in languages like Rust or Swift by providing Result types, stack traces, and "Logical Stack Traces" through macro-driven decoration.

It is part of the Zen Development Kit.

Features

  • Type-Safe Results: Generic result<T> patterns for both C (via macros) and C++.
  • Logical Stack Traces: Capture file, line, and function names at the point of origin and throughout the propagation chain.
  • Zero-Allocation Printing: Uses thread-local ring buffers for error message formatting to avoid heap fragmentation.
  • C++ Support: Native C++11 wrapper with RAII result<T> and std::ostream integration.
  • Modern C Ergonomics: Leverages __attribute__((cleanup)) and statement expressions for try-like syntax on supported compilers.
  • Debug Integration: Optional hardware breakpoints/traps (ZERROR_TRAP) when an error is created.

Usage: C

Define result types and use the propagation macros to handle errors without boilerplate.

#define ZERROR_IMPLEMENTATION
#include "zerror.h"

// Define a Result type that can return an int or a zerr.
DEFINE_RESULT(int, ResInt)

ResInt calculate(int val) 
{
    if (val < 0) 
    {
        // Creates error with file/line/func context.
        return ResInt_err(zerr_create(Z_EINVAL, "Value cannot be negative: %d", val));
    }
    return ResInt_ok(val * 2);
}

zres process() 
{
    // 'try' automatically unwraps value or returns error to caller.
    int x = try(calculate(-5)); 
    printf("Result: %d\n", x);
    return zres_ok();
}

int main() 
{
    // 'run' executes the logic and prints a formatted trace on failure.
    return run(process());
}

Usage: C++

The C++ wrapper lives in the z_error namespace and provides a template-based result<T> that behaves similarly to std::expected.

#include <iostream>
#define ZERROR_IMPLEMENTATION
#include "zerror.h"

z_error::result<int> compute(int n) 
{
    if (n == 0) 
    {
        return zerr_create(Z_ERR, "Division by zero");
    }
    return 100 / n;
}

int main()
{
    auto res = compute(0);
    if (!res) 
    {
        std::cerr << "Caught error: " << res.err << std::endl;
        return 1;
    }
    std::cout << "Value: " << res.unwrap_val() << std::endl;
    return 0;
}

API Reference (C)

Logging

Logging & Debugging

Function Description
zlog_init(path, level) Initializes logging to a file (optional) and sets min level.
zlog_set_level(level) Sets the minimum logging level at runtime.
log_info(...) Logs an info message (White).
log_warn(...) Logs a warning message (Yellow).
log_error(...) Logs an error message (Red).
log_debug(...) Logs a debug message (Cyan, if level permits).
log_trace(...) Logs a trace message (Blue, if level permits).

Error Types

Data Structures

Function / Macro Description
zerr Base error struct containing code, message, file, line, and trace info.
zres Standard void result type (contains is_ok and zerr).
ResInt Typed result carrying an int value or an error.
ResPtr Typed result carrying a void* value or an error.

Error Management

Creation & Manipulation

Type Description
zerr_create(code, msg) Creates a new error with current file/line context.
zerr_errno(code, msg) Creates a new error, appending the string description of errno.
zerr_wrap(e, fmt, ...) Wraps an existing error with a new context message.
zerr_print(e) Prints a stylized error report to stderr.
zerr_panic(msg) Prints a panic message and aborts the program.

Macros

Flow Control

Function Description
check(expr) Propagates error for functions returning zres or typed results.
check_into(Type, expr) Propagates error, converting it to a Type result.
check_wrap(expr, fmt) Propagates error with a wrapping context message.
try(expr) Evaluates expr. If error, returns it. Else returns the unwrapped value.
try_into(Type, expr) Same as try, but converts the error return type.
expect(expr, msg) Evaluates expr. If error, panics with msg.
ensure(cond, code, msg) Returns an error if cond is false.
run(expr) Executes entry point function (returning zres), printing errors on failure.

API Reference (C++)

C++ Helpers

Namespace z_log

Macro Description
z_log::info(fmt, ...) Logs an info message using C-style formatting.
z_log::warn(fmt, ...) Logs a warning message using C-style formatting.
z_log::error(fmt, ...) Logs an error message using C-style formatting.
z_log::info(str) Logs a std::string as info.
z_log::error(str) Logs a std::string as error.

Result Type

Class z_error::result

Function Description
result(val) Constructors for creating a success result (move or copy).
result(err) Constructors for creating a failure result from zerr or zres.
ok() Returns true if the result contains a value (success).
unwrap_val() Returns the contained value or panics if it is an error.
err Public member accessing the underlying zerr struct (valid only if !ok()).
operator bool() Implicit conversion to boolean (true = success).

C++ Macros

Shortcuts

Method Description
ztry(expr) Statement expression that unwraps a result<T> or returns the error immediately.

Configuration

Define these macros before including zerror.h to modify behavior:

Macro Description
ZERROR_IMPLEMENTATION Define in exactly one .c or .cpp file to generate logic.
ZERROR_SHORT_NAMES Enables shorter aliases (for example, try, check, ensure).
ZERROR_DEBUG Enables hardware traps/breakpoints at the exact moment an error is created.
ZERROR_ENABLE_TRACE Enables the collection of propagation traces.
ZERROR_NO_COLOR Disables ANSI color codes in zerr_print.
ZERROR_PANIC_ACTION Define to override the default abort() behavior.

Memory Management

zerror.h uses an internal thread-local ring buffer to handle error messages. This allows you to return formatted error messages from functions without worrying about malloc or free.

The common library (zcommon.h block) also allows you to override the standard allocators used by the system.

About

A zero-dependency, header-only error handling library for C/C++ implementing robust Result types and automatic stack tracing.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

  •  

Packages

No packages published