On this page

Exception Safety

Preliminary warning: Exception safety is not feature complete! Common cases should work, but classes might still leak or even crash.

Qt doesn't use exceptions to report errors. Instead, functions return a value that indicates failure, such as false from QFile::open(), and classes let you query the error afterward, for example with QIODevice::errorString() or QSqlQuery::lastError(). Some classes also emit a signal, such as QNetworkReply::errorOccurred(). Qt avoids exceptions for historical and practical reasons.

Qt throws exceptions in a few cases, such as when a memory allocation fails, as described in Out of Memory Handling. QFuture also passes on exceptions that a Qt Concurrent task throws.

The following sections describe how Qt behaves when you compile your application with exception support.

Exception Safe Modules

Containers

Qt's container classes are generally exception neutral. They pass any exception that happens within their contained type T to the user while keeping their internal state valid.

Example:

QList<QString> list;
...
try {
    list.append("hello");
} catch (...) {
}
// list is safe to use - the exception did not affect it.

Exceptions to that rule are containers for types that can throw during assignment or copy constructions. For those types, functions that modify the container as well as returning a value, are unsafe to use:

MyType s = list.takeAt(2);

If an exception occurs during the assignment of s, the value at index 2 is already removed from the container, but hasn't been assigned to s yet. It is lost without chance of recovery.

The correct way to write it:

MyType s = list.at(2);
list.removeAt(2);

If the assignment throws, the container will still contain the value; no data loss occurred.

Note that implicitly shared Qt classes will not throw in their assignment operators or copy constructors, so the limitation above does not apply.

Out of Memory Handling

In general, Qt doesn't handle out-of-memory conditions. Qt code assumes that memory allocations succeed, and the behavior of the application is undefined if one fails.

QList, QString, and QByteArray check their memory allocations with the Q_CHECK_PTR macro, which throws a std::bad_alloc exception if you compile your application with exception support. Without exception support, running out of memory is undefined behavior.

Some operating systems, such as Linux in its default configuration, overcommit memory. On such systems, malloc() or operator new can return a valid pointer even though there isn't enough memory available, and the system can terminate a process later when memory runs out. Allocations can still fail, for example if the requested size is very large.

Some classes report failed allocations in other ways, and document how. For example, QImage constructors create a null image instead of throwing an exception if there isn't enough memory.

Recovering from Exceptions

Currently, the only supported use case for recovering from exceptions thrown within Qt (for example due to out of memory) is to exit the event loop and do some cleanup before exiting the application.

Typical use case:

QApplication app(argc, argv);
...
int ret;
try {
    ret = app.exec();
} catch (const std::bad_alloc &) {
    // clean up here, e.g. save the session
    // and close all config files.

    return EXIT_FAILURE; // exit the application
}
...
return ret;

After an exception is thrown, the connection to the windowing server might already be closed. It is not safe to call a GUI related function after catching an exception.

Exceptions in Client Code

Signals and Slots

Throwing an exception from a slot invoked by Qt's signal-slot connection mechanism is considered undefined behaviour, unless it is handled within the slot:

State state;
StateListener stateListener;

// OK; the exception is handled before it leaves the slot.
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwHandledException()));
// Undefined behaviour; upon invocation of the slot, the exception will be propagated to the
// point of emission, unwinding the stack of the Qt code (which is not guaranteed to be exception safe).
QObject::connect(&state, SIGNAL(stateChanged()), &stateListener, SLOT(throwUnhandledException()));

If the slot was invoked directly, like a regular function call, exceptions may be used. This is because the connection mechanism is bypassed when invoking slots directly:

State state;
StateListener stateListener;

// ...

try {
    // OK; invoking slot directly.
    stateListener.throwException();
} catch (...) {
    qDebug() << "Handling exception not caught in slot.";
}

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.