OLD | NEW |
(Empty) | |
| 1 /** |
| 2 * \file handle.h The "install session" is the context for all custom installati
on behavior. |
| 3 */ |
| 4 |
| 5 #ifndef INSTALLER_LIB_H |
| 6 #define INSTALLER_LIB_H |
| 7 |
| 8 #include <stdexcept> |
| 9 #include <sstream> |
| 10 |
| 11 /** |
| 12 * Standard runtime error for failure of Windows API calls. |
| 13 * |
| 14 * The design purpose of this class is to consistently report the details of a f
ailed API call, with an eye toward logging. |
| 15 * All the arguments passed to the constructor appear in what(). |
| 16 * In addition the return value of GetLastError() appears. |
| 17 * |
| 18 * All the types for the constructors are generic. |
| 19 * Any type that works with the output operator '<<' of a stream will work. |
| 20 * |
| 21 * \par Example |
| 22 * For a simple error, where there's not much to add over the API call and the
error code itself, just omit the second argument. |
| 23 * \code |
| 24 * throw windows_api_error( "MsiDatabaseOpenView", "ERROR_BAD_QUERY_SYNTAX"
) |
| 25 * \endcode |
| 26 * |
| 27 * \par |
| 28 * Sometimes you don't have a symbolic error code. |
| 29 * This example uses a numeric error and a clarifying message. |
| 30 * \code |
| 31 * throw windows_api_error( "MsiOpenDatabaseW", x, "MSI database is on file
system" ) |
| 32 * \endcode |
| 33 */ |
| 34 class windows_api_error |
| 35 : public std::runtime_error |
| 36 { |
| 37 template< class T1, class T2, class T3 > |
| 38 static std::string make_message( T1 api_function, T2 error_code, T3 message ) |
| 39 { |
| 40 std::ostringstream r, t ; |
| 41 std::string s ; |
| 42 |
| 43 t << api_function ; |
| 44 s = t.str() ; |
| 45 if ( s.empty() ) |
| 46 { |
| 47 s = "<unspecified>" ; |
| 48 } |
| 49 r << s << " returned " ; |
| 50 |
| 51 t = std::ostringstream() ; |
| 52 t << error_code ; |
| 53 s = t.str() ; |
| 54 if ( s.empty() ) |
| 55 { |
| 56 s = "<unknown>" ; |
| 57 } |
| 58 r << s << " with last error code " << ::GetLastError() ; |
| 59 |
| 60 t = std::ostringstream() ; |
| 61 t << message ; |
| 62 s = t.str() ; |
| 63 if ( ! s.empty() ) |
| 64 { |
| 65 r << ": " << s ; |
| 66 } |
| 67 |
| 68 return r.str() ; |
| 69 } |
| 70 |
| 71 public: |
| 72 /** |
| 73 * Constructor with additional message. |
| 74 * |
| 75 * \param api_function |
| 76 * The name of the API function that returned an error code or a null handl
e. |
| 77 * \param error_code |
| 78 * The error code that the function returned, either symbolic or numeric. |
| 79 * Will be zero when the function returned a null handle. |
| 80 * \param message |
| 81 * Extra message to clarify the error |
| 82 */ |
| 83 template< class T1, class T2, class T3 > |
| 84 windows_api_error( T1 api_function, T2 error_code, T3 message ) |
| 85 : std::runtime_error( make_message( api_function, error_code, message ) ) |
| 86 {} |
| 87 |
| 88 /** |
| 89 * Constructor without anything extra. |
| 90 * |
| 91 * \param api_function |
| 92 * The name of the API function that returned an error code or a null handl
e. |
| 93 * \param error_code |
| 94 * The error code that the function returned, either symbolic or numeric. |
| 95 * Will be zero when the function returned a null handle. |
| 96 */ |
| 97 template< class T1, class T2 > |
| 98 windows_api_error( T1 api_function, T2 error_code ) |
| 99 : std::runtime_error( make_message( api_function, error_code, "" ) ) |
| 100 {} |
| 101 } ; |
| 102 |
| 103 /** |
| 104 */ |
| 105 class not_yet_supported |
| 106 : public std::runtime_error |
| 107 { |
| 108 public: |
| 109 not_yet_supported( std::string message ) |
| 110 : std::runtime_error( "Not yet supported: " + message ) |
| 111 {} |
| 112 } ; |
| 113 |
| 114 #endif |
OLD | NEW |