Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
e82758b
add(forward): adding new forward declaration for the error system
mallory-scotton May 1, 2026
46a29ca
add(error): adding new error record class to handle meta bag
mallory-scotton May 1, 2026
b33fe74
add(error): adding the implementation file for error record
mallory-scotton May 1, 2026
d84a3d4
add(errors): adding implementation for the sink base class
mallory-scotton May 1, 2026
2aed702
fix: fixing pragma in cpp file
mallory-scotton May 1, 2026
884f1a3
add(string): adding std::formatter overload for basic string view
mallory-scotton May 1, 2026
7202339
add: adding basci string formatting
mallory-scotton May 1, 2026
c4e3ce0
add(error): adding implementation for record summary
mallory-scotton May 1, 2026
c956c52
add(errors): adding plaeholders files for the different sinks
mallory-scotton May 1, 2026
7ac2eaf
add(container): adding new utility in basic string to implicitly conv…
mallory-scotton May 1, 2026
107b21d
add(errors): adding error context and scoped context with additional …
mallory-scotton May 1, 2026
b21b8fe
add(errors): adding error registry to handle documentation linking
mallory-scotton May 1, 2026
22c5030
add(main): adding temporary dump of all the errors
mallory-scotton May 1, 2026
b8bf7a5
update: updating naming of the config and severity file
mallory-scotton May 1, 2026
2c40a7e
add(errors): adding error filters and predicate
mallory-scotton May 1, 2026
6fd5dad
format: updating clang format rules about lambda indent
mallory-scotton May 1, 2026
b651138
add(vector): adding gp::eraseIf and gp::erase that mimics std::erase_if
mallory-scotton May 1, 2026
7d12d8b
fix(error): fix error record to fallback to a dummy stacktrace if not…
mallory-scotton May 1, 2026
ddfff1c
move(errors): move error sink out of the sinks
mallory-scotton May 1, 2026
cfef613
add(error): adding multi sink
mallory-scotton May 1, 2026
c8f79e5
add(error): adding main error system handler
mallory-scotton May 1, 2026
ed825ce
add(error): adding conveniance aliases to use error severity
mallory-scotton May 1, 2026
def987e
add(error) adding ability to raise error
mallory-scotton May 1, 2026
8c728f7
add: adding test in the main for the GP_ macros to raise errors
mallory-scotton May 1, 2026
25dd542
add: adding console sink for the error system
mallory-scotton May 1, 2026
d28013c
fix(errors): fixing banner not correctly showing that the stacktrace …
mallory-scotton May 1, 2026
2397e8d
remove(errors): removing unfinished sinks
mallory-scotton May 1, 2026
a17f6a3
add(errors): adding abort sink
mallory-scotton May 1, 2026
149692d
add(errors): adding breakpoint sink
mallory-scotton May 1, 2026
5b2e904
fix(iwyu): fixing iwyu in console sink
mallory-scotton May 1, 2026
7f73304
add(errors): adding file sink
mallory-scotton May 1, 2026
e91d335
add(forward): adding all classes to forward declarations of error
mallory-scotton May 1, 2026
1aae11b
add(errors): adding base sink on initialization of error system
mallory-scotton May 1, 2026
034b883
add: adding tests for the abort sink
mallory-scotton May 1, 2026
b0c4f97
fix: change constexpr config to inline
mallory-scotton May 1, 2026
055afe3
fix: change ErrorRegistry describe/remediationHint/wikiUrl return typ…
Copilot May 1, 2026
f86cd8d
fix(errors): fixing a lot of issues with error subsystem
mallory-scotton May 1, 2026
611a563
remove: removing expected since we are not using it right now
mallory-scotton May 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ MaxEmptyLinesToKeep: 1
MainIncludeChar: Any
LineEnding: CRLF
Language: Cpp
LambdaBodyIndentation: Signature
LambdaBodyIndentation: OuterScope
KeepEmptyLines:
AtEndOfFile: true
AtStartOfBlock: false
Expand Down
37 changes: 34 additions & 3 deletions source/launch/editor/private/Main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,49 @@
// mailto:support AT graphical-playground DOT com

#include "container/BasicString.hpp"
#include "container/BasicStringView.hpp"
#include "container/Forward.hpp"
#include "CoreMinimal.hpp"
#include "errors/Error.hpp"
#include "errors/ErrorConfig.hpp"
#include "errors/ErrorRegistry.hpp"
#include "errors/ErrorSystem.hpp"
#include <iostream>

int main()
int main(int argc, char* argv[])
{
std::cout << "Hello, Graphical Playground Editor!" << std::endl;
// TODO: Implement editor main function.

gp::String str = "Hello, World!";
std::cout << "gp::String says: " << str << std::endl;

auto& registry = gp::error::ErrorRegistry::instance();
std::cout << registry.dumpAll() << std::endl;

gp::error::ErrorSystemConfig config = gp::error::ErrorSystemConfig::getDevelopmentConfig();
config.abort.abortFrom = gp::error::Severity::Critical;
gp::error::ErrorSystem::initialize(config);

gp::Vector<gp::StringView> args;
for (int i = 0; i < argc; ++i)
{
args.pushBack(argv[i]);
}

for (const auto& arg: args)
{
// clang-format off
if (arg == "--trace") GP_TRACE("This is a trace message!");
else if (arg == "--debug") GP_DEBUG("This is a debug message!");
else if (arg == "--info") GP_INFO("This is an info message!");
else if (arg == "--warn") GP_WARN("This is a warning message!");
else if (arg == "--error") GP_ERROR("This is an error message!");
else if (arg == "--fatal") GP_FATAL("This is a fatal message!");
else if (arg == "--panic") GP_PANIC("This is a critical message!");
// clang-format on
}

gp::error::ErrorSystem::flushAll();
gp::error::ErrorSystem::shutdown();

return 0;
}
96 changes: 96 additions & 0 deletions source/runtime/core/private/errors/ErrorContext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) - Graphical Playground. All rights reserved.
// For more information, see https://graphical-playground/legal
// mailto:support AT graphical-playground DOT com

#include "errors/ErrorContext.hpp"
#include "CoreMinimal.hpp"

namespace gp::error
{

void ErrorContext::push(gp::String subsystem, gp::String operation)
{
m_stack.pushBack({ std::move(subsystem), std::move(operation), {} });
}

void ErrorContext::pop() noexcept
{
if (!m_stack.isEmpty())
{
m_stack.popBack();
}
}

void ErrorContext::tag(gp::String key, gp::String value)
{
if (!m_stack.isEmpty())
{
m_stack.back().tags.pushBack({ std::move(key), std::move(value) });
}
}

GP_NODISCARD bool ErrorContext::isEmpty() const noexcept
{
return m_stack.isEmpty();
}

GP_NODISCARD gp::USize ErrorContext::depth() const noexcept
{
return m_stack.size();
}

GP_NODISCARD const gp::Vector<ContextFrame>& ErrorContext::frames() const noexcept
{
return m_stack;
}

GP_NODISCARD gp::StringView ErrorContext::currentSubsystem() const noexcept
{
return m_stack.isEmpty() ? gp::StringView{} : m_stack.back().subsystem.asView();
}

GP_NODISCARD MetaBag ErrorContext::flatten() const
{
MetaBag out;

for (gp::USize i = 0; i < m_stack.size(); ++i)
{
const auto& frame = m_stack[i];
out.pushBack({ gp::String::format("scope[{}].subsystem", i), frame.subsystem });
out.pushBack({ gp::String::format("scope[{}].operation", i), frame.operation });
for (const auto& tag: frame.tags)
{
out.pushBack({ gp::String::format("scope[{}].{}", i, tag.key), tag.value });
}
}

return out;
}

void ErrorContext::setThreadName(gp::String name)
{
m_threadName = std::move(name);
}

GP_NODISCARD const gp::String& ErrorContext::threadName() const noexcept
{
return m_threadName;
}

ContextScope::ContextScope(gp::String subsystem, gp::String operation)
{
ErrorContext::current().push(std::move(subsystem), std::move(operation));
}

ContextScope::~ContextScope() noexcept
{
ErrorContext::current().pop();
}

ContextScope& ContextScope::tag(gp::String key, gp::String value)
{
ErrorContext::current().tag(std::move(key), std::move(value));
return *this;
}

} // namespace gp::error
133 changes: 133 additions & 0 deletions source/runtime/core/private/errors/ErrorRecord.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
// Copyright (c) - Graphical Playground. All rights reserved.
// For more information, see https://graphical-playground/legal
// mailto:support AT graphical-playground DOT com

#include "errors/ErrorRecord.hpp"
#include "errors/ErrorCode.hpp"
#include "errors/ErrorSeverity.hpp"
#include <ctime>
#include <functional>

Comment thread
mallory-scotton marked this conversation as resolved.
namespace gp::error
{

void ErrorRecord::addMetadata(gp::String key, gp::String value)
{
metadata.pushBack({ std::move(key), std::move(value) });
}

GP_NODISCARD gp::StringView ErrorRecord::getMetadata(gp::StringView key) const noexcept
{
for (const auto& entry: metadata)
{
if (entry.key == key)
{
return entry.value;
}
}
return {};
}

GP_NODISCARD bool ErrorRecord::hasCause() const noexcept
{
return cause != nullptr;
}

GP_NODISCARD gp::USize ErrorRecord::causeDepth() const noexcept
{
gp::USize depth = 0;
const ErrorRecord* current = cause.get();
while (current)
{
++depth;
current = current->cause.get();
}
return depth;
}

GP_NODISCARD gp::String ErrorRecord::summary() const
{
return gp::String::format(
"[{}][{}:0x{:04X}] {} ({}:{})",
getSeverityName(severity),
getDomainName(code.domain()),
code.code(),
message,
location.file_name(),
location.line()
);
}

GP_NODISCARD gp::String ErrorRecord::fullReport() const
{
gp::String out;
out.reserve(2048);

out += "╔══ GP ErrorRecord ═══════════════════════════════════════════╗\n";
out += gp::String::format("β•‘ Severity : {}\n", getSeverityDisplay(severity));
out += gp::String::format("β•‘ Code : [{}] 0x{:04X}\n", getDomainName(code.domain()), code.code());
out += gp::String::format("β•‘ Message : {}\n", message);
out += gp::String::format(
"β•‘ Location : {}:{} in {}\n", location.file_name(), location.line(), location.function_name()
);
out += gp::String::format(
"β•‘ Thread : {} ({})\n",
threadName.isEmpty() ? "unnamed" : threadName,
[&]
{
auto id = threadId;
std::hash<std::thread::id> hashThreadId;
return gp::String::format("{:#x}", hashThreadId(id));
}()
);

auto tt = std::chrono::system_clock::to_time_t(wallTime);
char tbuf[64]{};
struct tm tm{};
#if defined(_MSC_VER)
gmtime_s(&tm, &tt);
#else
gmtime_r(&tt, &tm);
#endif
strftime(tbuf, sizeof tbuf, "%Y-%m-%d %T UTC", &tm);
out += gp::String::format("β•‘ Timestamp : {}\n", tbuf);

if (!metadata.isEmpty())
{
out += "β•‘ Meta :\n";
for (const auto& m: metadata)
{
out += gp::String::format("β•‘ {} = {}\n", m.key, m.value);
}
}

#if GP_HAS_STACKTRACE
if (!stacktrace.empty())
{
out += "β•‘ Stacktrace:\n";
for (const auto& frame: stacktrace)
{
out += gp::String::format("β•‘ {}\n", std::to_string(frame));
}
}
#endif

if (hasCause())
{
out += "β•‘ Caused by :\n";
const ErrorRecord* c = cause.get();
int depth = 0;
while (c && depth < 8)
{
out += gp::String::format("β•‘ [{}] {}\n", getSeverityName(c->severity), c->message);
c = c->cause.get();
++depth;
}
}

out += "β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•\n";

return out;
}

} // namespace gp::error
Loading
Loading