|
|
// dexception
//
// Exception class
#pragma once
#include "shtl.h"
#include "tstring.h"
using namespace std;
class dexception { protected:
enum { hresult, text, unknown } m_type;
tstring m_text; HRESULT m_hr;
public:
virtual ~dexception() {}
dexception() : m_type(unknown) {}
dexception(const char * psz) : m_type(text), m_text(psz) {}
dexception(const tstring& xs) : m_type(text), m_text(xs) {}
dexception(const DWORD& dwError) : m_type(hresult), m_hr(HRESULT_FROM_WIN32(dwError)) {}
dexception(const HRESULT& hr) : m_type(hresult), m_hr(hr) {}
operator const HRESULT() const { return (m_type == hresult) ? m_hr : E_UNEXPECTED; }
tstring GetErrorText() { if (m_type == text) return m_text;
if (m_text.length()) return m_text;
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, m_hr, LANG_USER_DEFAULT, m_text.GetBuffer(255), 255, NULL); m_text.ReleaseBuffer(-1); return m_text; } };
// errorinfo_exception
//
// Exception class that knows how to set the last error for this
// thread using the IErrorInfo object
class errorinfo_exception : public dexception { private: CLSID m_clsid; IID m_iid; tstring m_str; public:
errorinfo_exception(const tstring & str, const HRESULT & hr, const CLSID & clsid, const IID & iid) : dexception(hr), m_clsid(clsid), m_iid(iid), m_str(str) { ASSERT(FAILED(hr)); }
HRESULT ReportError() const { return AtlReportError(m_clsid, m_str, m_iid, m_hr); }
};
// win32error
//
// Exception class that looks at GetLastError. By default, will
// use E_UNEXPECTED if GetLastError was not actually set by failing API.
class win32error : public dexception { public:
win32error(bool bEnsureFailure = true) { DWORD dwError = GetLastError(); m_type = hresult; m_hr = (dwError || !bEnsureFailure) ? HRESULT_FROM_WIN32(dwError) : E_UNEXPECTED; } };
// CATCH_AND_RETURN_AS_HRESULT
//
// Protects a block of code (such as an interface implementation) that can throw
// our exceptions, and if it catches any, converts to an HRESULT and returns it
// to the caller
#define CATCH_AND_RETURN_AS_HRESULT \
catch(const errorinfo_exception & e)\ { \ return e.ReportError(); \ } \ catch(const dexception & d) \ { \ return (HRESULT) d; \ }
|