error.h (4357B)
1 // SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com> 2 // SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0) 3 4 #pragma once 5 6 #include "small_string.h" 7 #include "types.h" 8 9 #include "fmt/core.h" 10 11 #include <string> 12 #include <string_view> 13 14 class Error 15 { 16 public: 17 Error(); 18 Error(const Error& e); 19 Error(Error&& e); 20 ~Error(); 21 22 enum class Type 23 { 24 None = 0, 25 Errno = 1, 26 Socket = 2, 27 User = 3, 28 Win32 = 4, 29 HResult = 5, 30 }; 31 32 ALWAYS_INLINE Type GetType() const { return m_type; } 33 ALWAYS_INLINE bool IsValid() const { return (m_type != Type::None); } 34 ALWAYS_INLINE const std::string& GetDescription() const { return m_description; } 35 ALWAYS_INLINE std::string TakeDescription() { return std::move(m_description); } 36 37 void Clear(); 38 39 /// Error that is set by system functions, such as open(). 40 void SetErrno(int err); 41 void SetErrno(std::string_view prefix, int err); 42 43 /// Error that is set by socket functions, such as socket(). On Unix this is the same as errno. 44 void SetSocket(int err); 45 void SetSocket(std::string_view prefix, int err); 46 47 /// Set both description and message. 48 void SetString(std::string description); 49 void SetStringView(std::string_view description); 50 51 #ifdef _WIN32 52 /// Error that is returned by some Win32 functions, such as RegOpenKeyEx. Also used by other APIs through 53 /// GetLastError(). 54 void SetWin32(unsigned long err); 55 void SetWin32(std::string_view prefix, unsigned long err); 56 57 /// Error that is returned by Win32 COM methods, e.g. S_OK. 58 void SetHResult(long err); 59 void SetHResult(std::string_view prefix, long err); 60 #endif 61 62 static Error CreateNone(); 63 static Error CreateErrno(int err); 64 static Error CreateSocket(int err); 65 static Error CreateString(std::string description); 66 #ifdef _WIN32 67 static Error CreateWin32(unsigned long err); 68 static Error CreateHResult(long err); 69 #endif 70 71 // helpers for setting 72 static void Clear(Error* errptr); 73 static void SetErrno(Error* errptr, int err); 74 static void SetErrno(Error* errptr, std::string_view prefix, int err); 75 static void SetSocket(Error* errptr, int err); 76 static void SetSocket(Error* errptr, std::string_view prefix, int err); 77 static void SetString(Error* errptr, std::string description); 78 static void SetStringView(Error* errptr, std::string_view description); 79 80 #ifdef _WIN32 81 static void SetWin32(Error* errptr, unsigned long err); 82 static void SetWin32(Error* errptr, std::string_view prefix, unsigned long err); 83 static void SetHResult(Error* errptr, long err); 84 static void SetHResult(Error* errptr, std::string_view prefix, long err); 85 #endif 86 87 /// Sets a formatted message. 88 template<typename... T> 89 static void SetStringFmt(Error* errptr, fmt::format_string<T...> fmt, T&&... args) 90 { 91 if (errptr) 92 Error::SetString(errptr, fmt::vformat(fmt, fmt::make_format_args(args...))); 93 } 94 95 void AddPrefix(std::string_view prefix); 96 void AddSuffix(std::string_view suffix); 97 static void AddPrefix(Error* errptr, std::string_view prefix); 98 static void AddSuffix(Error* errptr, std::string_view prefix); 99 100 template<typename... T> 101 void AddPrefixFmt(fmt::format_string<T...> fmt, T&&... args) 102 { 103 TinyString str; 104 fmt::vformat_to(std::back_inserter(str), fmt, fmt::make_format_args(args...)); 105 AddPrefix(str.view()); 106 } 107 108 template<typename... T> 109 void AddSuffixFmt(fmt::format_string<T...> fmt, T&&... args) 110 { 111 TinyString str; 112 fmt::vformat_to(std::back_inserter(str), fmt, fmt::make_format_args(args...)); 113 AddSuffix(str.view()); 114 } 115 116 template<typename... T> 117 static void AddPrefixFmt(Error* errptr, fmt::format_string<T...> fmt, T&&... args) 118 { 119 if (errptr) 120 { 121 TinyString str; 122 fmt::vformat_to(std::back_inserter(str), fmt, fmt::make_format_args(args...)); 123 errptr->AddPrefix(str.view()); 124 } 125 } 126 template<typename... T> 127 static void AddSuffixFmt(Error* errptr, fmt::format_string<T...> fmt, T&&... args) 128 { 129 if (errptr) 130 { 131 TinyString str; 132 fmt::vformat_to(std::back_inserter(str), fmt, fmt::make_format_args(args...)); 133 errptr->AddSuffix(str.view()); 134 } 135 } 136 137 Error& operator=(const Error& e); 138 Error& operator=(Error&& e); 139 bool operator==(const Error& e) const; 140 bool operator!=(const Error& e) const; 141 142 private: 143 Type m_type = Type::None; 144 std::string m_description; 145 };