title: Turning GetLastError() into an exception
body: <p>I have a Visual Studio 2008 C++ project that uses a <code>Win32Exception</code> class in cases where there is an <em>exceptional</em> error. The <code>Win32Exception</code> class looks like this:</p>
  
  <pre><code>/// defines an exception based on Win32 error codes. The what() function will
  /// return a formatted string returned from FormatMessage()
  class Win32Exception : public std::runtime_error
  {
  public:
      Win32Exception() : std::runtime_error( ErrorMessage( &amp;error_code_ ) )
      {
      };
  
      virtual ~Win32Exception() { };
  
      /// return the actual error code
      DWORD ErrorCode() const throw() { return error_code_; };
  
  private:
  
      static std::string ErrorMessage( DWORD* error_code )
      {
          *error_code = ::GetLastError();
  
          std::string error_messageA;
          wchar_t* error_messageW = NULL;
          DWORD len = ::FormatMessageW( FORMAT_MESSAGE_FROM_SYSTEM | 
                                        FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                        FORMAT_MESSAGE_IGNORE_INSERTS,
                                        NULL,
                                        *error_code,
                                        MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
                                        reinterpret_cast&lt; LPWSTR &gt;( &amp;error_messageW ),
                                        0,
                                        NULL );
          if( NULL != error_messageW )
          {
              // this may generate a C4244 warning. It is safe to ignore.
              std::copy( error_messageW, 
                         error_messageW + len, 
                         std::back_inserter( error_messageA ) );
              ::LocalFree( error_messageW );
          }
          return error_messageA;
      };
  
      /// error code returned by GetLastError()
      DWORD error_code_;
  
  }; // class Win32Exception
  </code></pre>
  
  <p>The class works well in the situations it has been used in. What I would like to know is if there are any obvious cases where this will fail that I should be aware of. Any other gotchas, caveats, or general suggestions on improvements are welcome.</p>
  
  <p>Please note that the boost library is not an option for this code.</p>