If I call a Win32 function that reports errors via GetLastError, for example RegisterClassEx, how do I throw a std::system_error for that error?
2 Answers
Check on the value of GetLastError()
like
DWORD dwErrVal = GetLastError();
std::error_code ec (dwErrVal, std::system_category());
throw std::system_error(ec, "Exception occurred");

- 13,029
- 3
- 29
- 42
-
Is it generic_category? Looking at the vc11 implementation it looks like maybe it should be system_category. – Michael Marcin Apr 06 '13 at 20:09
-
Thank you, didn't know it existed! – bash.d Apr 06 '13 at 20:13
-
Hmm, this doesn't seem to be working for me. GetLastError() is returning ERROR_INVALID_PARAMETER, but the system_error::what simply says "unknown error" – Mooing Duck May 28 '15 at 22:15
-
system_error is for errno codes, not Win32 codes. They're different. http://newscentral.exsees.com/item/d33ca604e6a55888937840570a5cd17d-76c1546f7ca7c2c00921bccdb34ec2d1 – Mooing Duck May 28 '15 at 22:28
-
@MooingDuck I think msvc's system_category implementation *is* meant for codes returned by GetLastError() but it only returns a proper message for a small subset of all codes - at least for VS2013 - and ERROR_INVALID_PARAMETER is not one of them. See _Winerror_map in syserror.cpp in the crt source code.. – stijn Jan 11 '16 at 20:51
-
1The whole `std::system_category()` thing in C++11 is a disaster when it comes to implementing on Win32 platform. Check **[this](http://stackoverflow.com/questions/28746372/system-error-categories-and-standard-system-error-codes)** out. There is basically no provision in the standard for systems which have *both* `errno` *and* native error codes. – rustyx Jun 03 '16 at 09:19
-
@stijn AFAIK, syserror.cpp only defines Windows to POSIX mapping, by design, what does not cover all Windows errors. However, other Windows codes are covered too. In VS2017, `std::error_code(ERROR_INVALID_PARAMETER, std::system_category()).message();` gives "The parameter is incorrect." as expected. – mloskot May 26 '17 at 21:24
-
@RustyX Not true. System error codes should be used with `system_category`, **and** it will be comparable to `std::errc` constants. If using Visual C++ 2015 or later (available when you commented), it is true that `std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory` *and* `std::error_code(ERROR_PATH_NOT_FOUND, std::system_category()) == std::errc::no_such_file_or_directory`. – Yongwei Wu Sep 23 '17 at 13:52
-
I can add to this, that `boost::system::error_code(::GetLastError(), boost::system::system_category())` works as expected on msvc2013; boost 1_59 at least – Vasilly.Prokopyev Feb 04 '19 at 18:11
Be aware that comparing a std::error_code
in the category of std::system_category()
doesn't generally work with the std::errc
enumeration constants depending on your vendor. E.g.
std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()) != std::errc::no_such_file_or_directory)
Certain vendors require using std::generic_category()
for that to work.
In MinGW std::error_code(ERROR_FILE_NOT_FOUND, std::system_category()).message()
won't give you the correct message.
For a truly portable and robust solution I would recommend subclassing both std::system_error
and std::system_category
to windows_error
and windows_category
and implement the correct functionality yourself. YMMV, VS2017 has been reported to work as one would expect.

- 1
- 1

- 91
- 1
- 2
-
2Someone has got to have made this alreadyright? But I can't find one :( – Mooing Duck Oct 15 '13 at 21:05
-
I am writing in 2017, so I am at a big advantage. This said, there are several problems with your answer. The reason your first example failed was because your should have used `ERROR_FILE_NOT_FOUND`. Secondly, even `ERROR_PATH_NOT_FOUND` will work under Visual C++ 2017 (but not 2013), as long as you use `system_category`. Yes, it only works correctly when one uses `system_category`, but not `generic_category`. Microsoft has made it work very well. – Yongwei Wu Sep 23 '17 at 13:33