Skip to content

Commit bbc8d3b

Browse files
committed
🚚 Use an actual error type for LoaderData issues
1 parent de8d6f3 commit bbc8d3b

File tree

4 files changed

+57
-16
lines changed

4 files changed

+57
-16
lines changed

‎src/LoaderData.hpp‎

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,39 @@
55
#include <openxr/openxr.h>
66

77
#include <string>
8+
#include <system_error>
89
#include <unordered_set>
10+
#include <variant>
911

1012
namespace FredEmmott::OpenXRLayers {
1113

1214
struct LoaderData {
15+
struct PipeCreationError {
16+
std::error_code mError;
17+
};
18+
struct PipeAttributeError {
19+
std::error_code mError;
20+
};
21+
struct CanNotFindExecutableError {
22+
std::error_code mError;
23+
};
24+
struct CanNotSpawnError {
25+
std::error_code mError;
26+
};
27+
struct BadExitCodeError {
28+
uint32_t mExitCode;
29+
};
30+
struct InvalidJSONError {
31+
std::string mExplanation;
32+
};
33+
using Error = std::variant<
34+
PipeCreationError,
35+
PipeAttributeError,
36+
CanNotFindExecutableError,
37+
CanNotSpawnError,
38+
BadExitCodeError,
39+
InvalidJSONError>;
40+
1341
XrResult mQueryExtensionsResult {XR_RESULT_MAX_ENUM};
1442
XrResult mQueryLayersResult {XR_RESULT_MAX_ENUM};
1543

‎src/Platform.hpp‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
#include <imgui.h>
1111

1212
#include "APILayerSignature.hpp"
13+
#include "LoaderData.hpp"
1314

1415
namespace FredEmmott::OpenXRLayers {
1516
class APILayerStore;
1617
class ReadWriteAPILayerStore;
17-
struct LoaderData;
1818

1919
struct DPIChangeInfo {
2020
float mDPIScaling {};
@@ -70,7 +70,7 @@ class Platform {
7070

7171
virtual std::expected<APILayerSignature, APILayerSignature::Error>
7272
GetAPILayerSignature(const std::filesystem::path&) = 0;
73-
virtual std::expected<LoaderData, std::string> GetLoaderData() = 0;
73+
virtual std::expected<LoaderData, LoaderData::Error> GetLoaderData() = 0;
7474
virtual std::vector<std::filesystem::path> GetNewAPILayerJSONPaths() = 0;
7575
virtual std::optional<std::filesystem::path> GetExportFilePath() = 0;
7676
virtual std::unordered_set<std::string> GetEnvironmentVariableNames() = 0;

‎src/windows/WindowsPlatform.cpp‎

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -574,14 +574,26 @@ std::vector<std::filesystem::path> WindowsPlatform::GetNewAPILayerJSONPaths() {
574574
return ret;
575575
}
576576

577-
std::expected<LoaderData, std::string> WindowsPlatform::GetLoaderData() {
577+
template <class T>
578+
static std::unexpected<T> UnexpectedHRESULT(HRESULT value) {
579+
return std::unexpected {
580+
T {{value, std::system_category()}},
581+
};
582+
}
583+
584+
template <class T>
585+
static std::unexpected<T> UnexpectedGetLastError() {
586+
return UnexpectedHRESULT<T>(HRESULT_FROM_WIN32(GetLastError()));
587+
}
588+
589+
std::expected<LoaderData, LoaderData::Error> WindowsPlatform::GetLoaderData() {
578590
if (!mLoaderData) {
579591
mLoaderData = GetLoaderDataWithoutCache();
580592
}
581593
return mLoaderData.value();
582594
}
583595

584-
std::expected<LoaderData, std::string>
596+
std::expected<LoaderData, LoaderData::Error>
585597
WindowsPlatform::GetLoaderDataWithoutCache() {
586598
SECURITY_ATTRIBUTES saAttr {
587599
.nLength = sizeof(SECURITY_ATTRIBUTES),
@@ -591,15 +603,16 @@ WindowsPlatform::GetLoaderDataWithoutCache() {
591603
wil::unique_handle stdoutRead;
592604
wil::unique_handle stdoutWrite;
593605
if (!CreatePipe(stdoutRead.put(), stdoutWrite.put(), &saAttr, 0)) {
594-
return std::unexpected("Failed to create pipe");
606+
return UnexpectedGetLastError<LoaderData::PipeCreationError>();
595607
}
596608
if (!SetHandleInformation(stdoutRead.get(), HANDLE_FLAG_INHERIT, 0)) {
597-
return std::unexpected("Failed to set pipe properties");
609+
return UnexpectedGetLastError<LoaderData::PipeAttributeError>();
598610
}
599611

600-
wchar_t modulePath[MAX_PATH];
601-
if (!GetModuleFileNameW(nullptr, modulePath, MAX_PATH)) {
602-
return std::unexpected("Failed to get executable path");
612+
constexpr auto MaxPathExtended = 32768;
613+
wchar_t modulePath[MaxPathExtended];
614+
if (!GetModuleFileNameW(nullptr, modulePath, MaxPathExtended)) {
615+
return UnexpectedGetLastError<LoaderData::CanNotFindExecutableError>();
603616
}
604617

605618
STARTUPINFOW si {
@@ -623,7 +636,7 @@ WindowsPlatform::GetLoaderDataWithoutCache() {
623636
nullptr,
624637
&si,
625638
&pi)) {
626-
return std::unexpected("Failed to create process");
639+
return UnexpectedGetLastError<LoaderData::CanNotSpawnError>();
627640
}
628641

629642
wil::unique_handle process {pi.hProcess};
@@ -643,14 +656,13 @@ WindowsPlatform::GetLoaderDataWithoutCache() {
643656

644657
DWORD exitCode;
645658
if (!GetExitCodeProcess(process.get(), &exitCode) || exitCode != 0) {
646-
return std::unexpected(
647-
std::format("Subprocess failed with exit code {}", exitCode));
659+
return std::unexpected {LoaderData::BadExitCodeError {exitCode}};
648660
}
649661

650662
try {
651663
return static_cast<LoaderData>(nlohmann::json::parse(output));
652664
} catch (const nlohmann::json::exception& e) {
653-
return std::unexpected(e.what());
665+
return std::unexpected {LoaderData::InvalidJSONError {e.what()}};
654666
}
655667
}
656668

‎src/windows/WindowsPlatform.hpp‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class WindowsPlatform final : public Platform {
2020

2121
std::optional<std::filesystem::path> GetExportFilePath() override;
2222
std::vector<std::filesystem::path> GetNewAPILayerJSONPaths() override;
23-
std::expected<LoaderData, std::string> GetLoaderData() override;
23+
std::expected<LoaderData, LoaderData::Error> GetLoaderData() override;
2424

2525
float GetDPIScaling() override {
2626
return mDPIScaling;
@@ -58,7 +58,7 @@ class WindowsPlatform final : public Platform {
5858
Config::MINIMUM_WINDOW_WIDTH,
5959
Config::MINIMUM_WINDOW_HEIGHT,
6060
};
61-
std::optional<std::expected<LoaderData, std::string>> mLoaderData;
61+
std::optional<std::expected<LoaderData, LoaderData::Error>> mLoaderData;
6262

6363
HWND CreateAppWindow();
6464
void InitializeFonts(ImGuiIO* io);
@@ -71,7 +71,8 @@ class WindowsPlatform final : public Platform {
7171
void MainLoop(const std::function<void()>& drawFrame);
7272
void Shutdown();
7373

74-
static std::expected<LoaderData, std::string> GetLoaderDataWithoutCache();
74+
static std::expected<LoaderData, LoaderData::Error>
75+
GetLoaderDataWithoutCache();
7576
static LRESULT WindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
7677

7778
LRESULT

0 commit comments

Comments
 (0)