# How to Handle Exceptions with fmtlib: A Complete Guide to format_error and FMT_THROW

> Master fmtlib exception handling using fmt::format_error and FMT_THROW. Learn to manage errors effectively and compile without exceptions for robust C++ applications.

- Repository: [Hello World Foundation/fmt](https://github.com/fmtlib/fmt)
- Tags: how-to-guide
- Published: 2026-09-06

---

**fmtlib uses `fmt::format_error`—a `std::runtime_error` subclass—thrown via the `FMT_THROW` macro, with built-in support for compiling without exceptions.**

The {fmt} library (commonly known as **fmtlib**) provides a minimal, predictable exception hierarchy for reporting formatting failures. Understanding how to catch, customize, or disable these exceptions is essential for robust error handling in C++ applications. This guide covers the complete exception-handling mechanism as implemented in `fmtlib/fmt`.

## The fmt::format_error Exception Type

All formatting errors in fmtlib raise **`fmt::format_error`**, defined in [[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) at lines 1112–1115:

```cpp
class format_error : public std::runtime_error {
 public:
  using std::runtime_error::runtime_error;
};

```

This single exception type handles every error condition—malformed format strings, type mismatches, compilation failures, and system-level I/O problems. Because it inherits from `std::runtime_error`, you can catch it specifically or handle it generically through `std::exception`.

## The FMT_THROW Macro: How Exceptions Are Raised

fmtlib abstracts all throw operations through the **`FMT_THROW`** macro, defined in [[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) at lines 162–168:

```cpp
#ifdef FMT_THROW
   // use user-provided definition
#elif FMT_USE_EXCEPTIONS
   #define FMT_THROW(x) throw x
#else
   #define FMT_THROW(x) ::fmt::assert_fail(__FILE__, __LINE__, (x).what())
#endif

```

The macro provides three behaviors:

- **User override**: Define `FMT_THROW` before including fmt headers to inject custom error handling
- **Standard mode** (default): When `FMT_USE_EXCEPTIONS` is defined, expands to normal `throw`
- **Exception-free mode**: Calls `fmt::assert_fail`, which prints diagnostics and aborts the program

This design allows the same source code to compile with or without exception support.

## Where fmtlib Throws Exceptions

Formatting errors originate from several core headers:

- **[[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)** – Malformed format strings such as missing closing braces throw `FMT_THROW(format_error("unmatched '{' in format string"))` at line 390
- **[[`include/fmt/compile.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h)** – Compile-time format validation failures
- **[[`include/fmt/chrono.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h)** – Date/time parsing and formatting errors
- **[[`include/fmt/xchar.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/xchar.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/xchar.h)** – System-level failures such as `FMT_THROW(system_error(errno, FMT_STRING("cannot write to file")))` at line 316
- **[[`include/fmt/format-inl.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format-inl.h)** – Runtime errors including memory allocation failures

## Catching fmtlib Exceptions

Catch `fmt::format_error` specifically for targeted handling, or use `std::exception` for broad coverage:

```cpp
#include <fmt/core.h>
#include <iostream>

int main() {
    try {
        // Malformed format string: missing '}'
        fmt::print("Hello {0!\n", 42);
    } catch (const fmt::format_error& e) {
        // Specific fmt exception handling
        std::cerr << "fmt error: " << e.what() << '\n';
    } catch (const std::exception& e) {
        // Generic fallback
        std::cerr << "standard error: " << e.what() << '\n';
    }
}

```

The `what()` message originates from the string passed to `format_error`'s constructor, providing actionable diagnostics.

## Compiling fmtlib Without Exceptions

For projects that disable C++ exceptions, define `FMT_USE_EXCEPTIONS=0` before including fmt headers or pass it to your compiler:

```cpp
#define FMT_USE_EXCEPTIONS 0
#include <fmt/core.h>

int main() {
    // Formatting errors now trigger abort via fmt::assert_fail
    fmt::print("Bad { format\n");
}

```

With exceptions disabled:
- `FMT_THROW` expands to `fmt::assert_fail(__FILE__, __LINE__, message)`
- The program prints the file, line, and error message, then terminates
- Behavior matches standard assertion failures—no stack unwinding occurs

## Customizing Error Handling with FMT_THROW

Override the `FMT_THROW` macro to redirect errors without modifying fmtlib source:

```cpp
#include <iostream>

#define FMT_THROW(e) (std::cerr << "Custom handler: " << (e).what() << '\n', throw e)

#include <fmt/core.h>

int main() {
    try {
        fmt::print("{:invalid}\n", 42);
    } catch (const std::exception& e) {
        // Handler executes before throw
    }
}

```

Place this definition before any fmt include to intercept all error sites across [[`format.h`](https://github.com/fmtlib/fmt/blob/main/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), [[`compile.h`](https://github.com/fmtlib/fmt/blob/main/compile.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/compile.h), [[`chrono.h`](https://github.com/fmtlib/fmt/blob/main/chrono.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/chrono.h), and [[`xchar.h`](https://github.com/fmtlib/fmt/blob/main/xchar.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/xchar.h).

## Summary

- **Single exception type**: `fmt::format_error` inherits from `std::runtime_error` and handles all formatting errors
- **Macro abstraction**: `FMT_THROW` controls whether to throw, abort, or call custom handlers
- **Exception-free builds**: Define `FMT_USE_EXCEPTIONS=0` to replace throws with `fmt::assert_fail`
- **Flexible catching**: Target `fmt::format_error` specifically or catch through `std::exception`
- **Customization hook**: Pre-define `FMT_THROW` to inject project-specific error handling

## Frequently Asked Questions

### What exception does fmtlib throw for invalid format strings?

fmtlib throws `fmt::format_error` for all format string errors. This type is defined in [[`include/fmt/format.h`](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h) at lines 1112–1115 and inherits from `std::runtime_error`. The exception includes a descriptive message accessible via `what()`.

### Can I use fmtlib in a project compiled without C++ exceptions?

Yes. Define `FMT_USE_EXCEPTIONS=0` before including fmt headers. In this mode, `FMT_THROW` expands to `fmt::assert_fail`, which prints the error location and message, then aborts. The same source code works in both configurations without modification.

### How do I catch fmtlib errors in a generic exception handler?

Catch `const std::exception&` or `const std::runtime_error&`, since `fmt::format_error` inherits from both. For targeted handling, catch `const fmt::format_error&` specifically. The library throws no other custom exception types, keeping the surface area minimal.

### Is there a way to customize fmtlib's error handling without modifying the library?

Yes. Pre-define the `FMT_THROW` macro with your own implementation before including any fmt headers. Your macro receives the exception object as its argument and can log, transform, or rethrow as needed. This affects all error sites including [[`format.h`](https://github.com/fmtlib/fmt/blob/main/format.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/format.h), [[`xchar.h`](https://github.com/fmtlib/fmt/blob/main/xchar.h)](https://github.com/fmtlib/fmt/blob/main/include/fmt/xchar.h), and other headers.