I'm writing on C++. Most of my code throw exceptions when fail. Sometimes I have to deal with the Window API that is C-oriented and does not throw. So, every time I call a WINAPI function I check the return value and if it indicate an error I use GetLastError()
to retrieve the concrete error code. Then I convert that error code in to an error string and throw an exception based on it.
For example:
HANDLE ph = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (!ph) {
throw std::runtime_error(win_error_to_string(GetLastError()));
}
I was wondering if it is appropriate to write an generic wrapper that invoke a WINAPI function an throw exception if an error was set during the call. Something like that:
template <typename R, typename... Args>
decltype(auto) call_winapi(R(WINAPI*func)(Args...), Args... &&args)
{
SetLastError(ERROR_SUCCESS);
const R result = func(args);
const DWORD error = GetLastError();
if (error != ERROR_SUCCESS) {
throw std::runtime_error(win_error_to_string(error));
}
return result;
}
The advantage of that technique is that I do not have to check the return value after each WINAPI call, assuming that the result is correct if the function does not throw.
HANDLE ph = call_winapi(OpenProcess, PROCESS_QUERY_INFORMATION, FASLE, pid);
But I'm afraid I missed something. Like, is it always true that if the WINAPI function set an error code that differ from ERROR_SUCCESS that means that the function failed?