diff --git a/subprocess.hpp b/subprocess.hpp index 62cfa92..10c3a87 100755 --- a/subprocess.hpp +++ b/subprocess.hpp @@ -148,7 +148,7 @@ class OSError: public std::runtime_error { public: OSError(const std::string& err_msg, int err_code): - std::runtime_error( err_msg + " : " + std::strerror(err_code) ) + std::runtime_error( err_msg + ": " + std::strerror(err_code) ) {} }; @@ -235,16 +235,15 @@ namespace util } #ifdef __USING_WINDOWS__ - inline std::string get_last_error() + inline std::string get_last_error(DWORD errorMessageID) { - DWORD errorMessageID = ::GetLastError(); if (errorMessageID == 0) return std::string(); LPSTR messageBuffer = nullptr; size_t size = FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, + FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); @@ -1554,8 +1553,10 @@ inline void Popen::execute_process() noexcept(false) &piProcInfo); // receives PROCESS_INFORMATION // If an error occurs, exit the application. - if (!bSuccess) - throw OSError("CreateProcessW failed", 0); + if (!bSuccess) { + DWORD errorMessageID = ::GetLastError(); + throw CalledProcessError("CreateProcess failed: " + util::get_last_error(errorMessageID), errorMessageID); + } CloseHandle(piProcInfo.hThread); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f61e5d2..74e8f82 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -1,4 +1,4 @@ -set(test_names test_subprocess test_cat test_env test_err_redirection test_split test_main test_ret_code) +set(test_names test_subprocess test_cat test_env test_err_redirection test_exception test_split test_main test_ret_code) set(test_files env_script.sh write_err.sh write_err.txt) diff --git a/test/test_exception.cc b/test/test_exception.cc new file mode 100644 index 0000000..51f4fb1 --- /dev/null +++ b/test/test_exception.cc @@ -0,0 +1,27 @@ +#include +#include +#include + +namespace sp = subprocess; + +void test_exception() +{ + bool caught = false; + try { + auto p = sp::Popen("invalid_command"); + assert(false); // Expected to throw + } catch (sp::CalledProcessError& e) { +#ifdef __USING_WINDOWS__ + assert(std::strstr(e.what(), "CreateProcess failed: The system cannot find the file specified.")); +#else + assert(std::strstr(e.what(), "execve failed: No such file or directory")); +#endif + caught = true; + } + assert(caught); +} + +int main() { + test_exception(); + return 0; +}