I am using the C library libusb. libusb methods return libusb_error enum values to signify errors. I want these methods to throw exceptions instead.
Each libusb error has a description that can be retrieved through the libusb_strerror() function. I want this to be what the what() method of thrown exceptions return.
My first attempt involved a wrapper function that throws a std::runtime_error constructed with the error description:
libusb_error wrapper(libusb_error error) { if(error >= 0) return error; throw std::runtime_error(libusb_strerror(error)); } But using that approach means I cannot catch libusb errors only nor specific libusb errors.
I then made a templated subclass of std::exception for libusb errors:
template<libusb_error error> class LIBUSBError : public std::exception { using std::exception::exception; virtual const char* what() const throw() { return libusb_strerror(error); } }; That approach allows me to catch specific libusb errors. However, template parameters have to be constant expressions, requiring me to use multiple statements for each enum value in my wrapper function:
// * * * libusb_error wrapper(libusb_error error) { if(error >= 0) return error; if(error == LIBUSB_ERROR_IO) { throw LIBUSBError<LIBUSB_ERROR_IO>(); } if(error == LIBUSB_ERROR_ACCESS) { throw LIBUSBError<LIBUSB_ERROR_ACCESS>(); } // ... etc } // * * * try { wrapper(libusb_open(device, &handle)); } catch(LIBUSBError<LIBUSB_ERROR_ACCESS> e) { std::cerr << e; continue; } // * * * How can I convert return values of the libusb methods into C++ exceptions without requiring me to write out each enum value?
LIBUSBErrorwhich will accept one argument (enum value) and constructstd::exceptionfrom it accordingly.