Skip to content

AException#

Abstract AUI exception.

Header:#include <AUI/Common/AException.h>
CMake:aui_link(my_target PUBLIC aui::core)

Detailed Description#

AException is the base exception type in AUI. It extends std::exception with automatic stack trace capture, lazy message formatting, and exception nesting (causal chains).

At the point of throwing, stack trace does not resolve symbol names and source lines. These are resolved when exception is printed.

main.cpp
static constexpr auto LOG_TAG = "MyApp";

int main() {
  try {
     throw AException("test");
  } catch (const AException& e) {
     ALogger::info(LOG_TAG) << "Operation failed: " << e;
  }
}
Possible output
Operation failed: test
- 0x00000000700000f0 main at main.cpp:5

Exceptions are chained automatically with std::current_exception(). This means you can throw another exception in catch block to populate the error message since callers tend to have wider context. If AException has a nested exception, it will be printed as well.

main.cpp
static constexpr auto LOG_TAG = "MyApp";

int safeDiv(int a, int b) {
   if (b == 0) {
       throw AException("divider is zero");
   }
   return a / b;
}

int readData(AStringView path) {
   try {
       AFileInputStream fis(path);
       int a, b;
       fis >> a >> b;
       return safeDiv(a, b);
   } catch (const AException&) {
       // add file path information. the original exception will
       // be carried by the new one.
       throw AException("can't read file \"{}\""_format(path));
   }
}

int main() {
   try {
      auto data = readData("data.bin");
      // ...
   } catch (const AException& e) {
      ALogger::err(LOG_TAG) << "Operation failed: " << e;
   }
}
Possible output
Operation failed: can't read file "data.bin"
- 0x0000000070000f00 readData at main.cpp:19
- 0x00000000700000f0 main at main.cpp:25
Caused by: divider is zero
- 0x0000000070001000 safeDiv at main.cpp:5
- 0x0000000070000f00 readData at main.cpp:15
- 0x00000000700000f0 main at main.cpp:25

Examples#

examples/7guis/cells/src/Functions.cpp

7GUIs Cells - Spreadsheet processor (Excel).

            } },
        { "IF",
            [](Ctx ctx) {
              if (ctx.args.size() != 3) {
                  throw AException("ARG");
              }
              auto condition = std::get_if<double>(&ctx.args[0]);
              if (condition == nullptr) {
                  throw AException("ARG0");
              }

examples/7guis/cells/src/Spreadsheet.h

7GUIs Cells - Spreadsheet processor (Excel).

    Cell& operator[](glm::uvec2 pos) { return *mCells[pos.y * mSize.x + pos.x]; }

    const Cell& operator[](glm::uvec2 pos) const {
        if (glm::any(glm::greaterThanEqual(pos, mSize))) {
            throw AException("OUTOFBOUNDS");
        }
        return *mCells[pos.y * mSize.x + pos.x];
    }

    auto operator[](formula::Range range) const {

examples/7guis/cells/src/AST.cpp

7GUIs Cells - Spreadsheet processor (Excel).

const T& expect(const Variant& variant) {
    if (std::holds_alternative<T>(variant)) {
        return std::get<T>(variant);
    }
    throw AException("VALUE {}"_format(AClass<T>::name()).uppercase());
}

struct BinaryOperatorNode : public INode {
    _unique<INode> left;
    _unique<INode> right;

examples/7guis/cells/src/Tokens.cpp

7GUIs Cells - Spreadsheet processor (Excel).

                        t->reverseByte();
                        out << token::Identifier { t->readStringWhile([](char c) -> bool { return std::isalnum(c); }) };
                        continue;
                    }
                    throw AException("UNEXPECTED {}"_format(c));
            }
        }
    } catch (const AEOFException&) {}
    return out;
}