From e606bdbf59f4123a192f81e59182dd35bf45a765 Mon Sep 17 00:00:00 2001 From: superp00t Date: Thu, 17 Aug 2023 02:02:23 -0400 Subject: [PATCH] feat(error): make errors visible on Windows --- storm/Error.cpp | 4 ++ storm/error/win/Display.cpp | 97 +++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 storm/error/win/Display.cpp diff --git a/storm/Error.cpp b/storm/Error.cpp index 9c8b239..c7fae26 100644 --- a/storm/Error.cpp +++ b/storm/Error.cpp @@ -9,6 +9,8 @@ static uint32_t s_lasterror = ERROR_SUCCESS; +#if !defined(WHOA_SYSTEM_WIN) + [[noreturn]] void SErrDisplayAppFatal(const char* format, ...) { va_list args; va_start(args, format); @@ -59,6 +61,8 @@ int32_t SErrDisplayError(uint32_t errorcode, const char* filename, int32_t linen } } +#endif + int32_t SErrDisplayErrorFmt(uint32_t errorcode, const char* filename, int32_t linenumber, int32_t recoverable, uint32_t exitcode, const char* format, ...) { char buffer[2048]; diff --git a/storm/error/win/Display.cpp b/storm/error/win/Display.cpp new file mode 100644 index 0000000..324a824 --- /dev/null +++ b/storm/error/win/Display.cpp @@ -0,0 +1,97 @@ +#include "storm/Error.hpp" + +#include +#include +#include +#include + +std::string errorf(const char *format, ...) { + va_list args; + va_start(args, format); + + constexpr size_t size = 1024; + + char buf[size] = {0}; + auto n = snprintf(buf, size, format, args); + + va_end(args); + + if (n < 0) { + return ""; + } else if (n >= size) { + std::string result(buf, n); + return result; + } else { + return std::string(buf); + } +} + +[[noreturn]] void SErrDisplayAppFatal(const char* format, ...) { + // Format arguments + constexpr size_t size = 1024; + char buffer[size] = {0}; + va_list args; + va_start(args, format); + vsnprintf(buffer, size, format, args); + va_end(args); + + // Print formatted message to debugger + OutputDebugString(buffer); + + // Display error to GUI + MessageBox(nullptr, buffer, "Fatal error!", MB_ICONERROR); + + exit(EXIT_FAILURE); +} + +int32_t SErrDisplayError(uint32_t errorcode, const char* filename, int32_t linenumber, const char* description, int32_t recoverable, uint32_t exitcode, uint32_t a7) { + std::string s = ""; + s.reserve(1024); + + s += errorf("\n=========================================================\n"); + + if (linenumber == -5) { + s += errorf("Exception Raised!\n\n"); + + s += errorf(" App: %s\n", "GenericBlizzardApp"); + + if (errorcode != 0x85100000) { + s += errorf(" Error Code: 0x%08X\n", errorcode); + } + + // TODO output time + + s += errorf(" Error: %s\n\n", description); + } else { + s += errorf("Assertion Failed!\n\n"); + + s += errorf(" App: %s\n", "GenericBlizzardApp"); + s += errorf(" File: %s\n", filename); + s += errorf(" Line: %d\n", linenumber); + + if (errorcode != 0x85100000) { + s += errorf(" Error Code: 0x%08X\n", errorcode); + } + + // TODO output time + + s += errorf(" Assertion: %s\n", description); + } + + // Print error in debugger + OutputDebugString(s.c_str()); + + // Title + const char* caption = recoverable ? "Error" : "Unrecoverable error"; + + // Icon/type + UINT icon = recoverable ? MB_ICONWARNING : MB_ICONERROR; + + MessageBox(nullptr, s.c_str(), caption, icon); + + if (recoverable) { + return 1; + } else { + exit(exitcode); + } +}