GME  13
CommonError.cpp
Go to the documentation of this file.
00001 
00002 #include "stdafx.h"
00003 #include "CommonError.h"
00004 #include "CommonSmart.h"
00005 #include <stdio.h>
00006 
00007 // --------------------------- hresult_exception
00008 
00009 hresult_exception::hresult_exception()
00010 {
00011         hr = 0;
00012 }
00013 
00014 hresult_exception::hresult_exception(const hresult_exception &e)
00015 {
00016         hr = e.hr;
00017 }
00018 
00019 hresult_exception::hresult_exception(HRESULT a)
00020 {
00021         hr = a;
00022 }
00023 
00024 hresult_exception &hresult_exception::operator=(const hresult_exception &e)
00025 {
00026         hr = e.hr;
00027         return *this;
00028 }
00029 
00030 hresult_exception &hresult_exception::operator=(HRESULT a)
00031 {
00032         hr = a;
00033         return *this;
00034 }
00035 
00036 hresult_exception::~hresult_exception()
00037 {
00038 }
00039 
00040 const char *hresult_exception::what() const
00041 {
00042         static char message[80];
00043         sprintf_s(message, sizeof(message), "HRESULT (0x%08lx) exception", hr);
00044         return message;
00045 }
00046 
00047 // --------------------------- Error Codes
00048 
00049 LPOLESTR common_descs[] = 
00050 {
00051         OLESTR("Improper use of object"),
00052         OLESTR("Unknown exception"),
00053         OLESTR("Data conversion has failed"),
00054         OLESTR("Requested != count in GetAll"),
00055         OLESTR("[out] parameter is not empty"),
00056         OLESTR("Passed interface is not from the same project"),
00057         OLESTR("Object was not found"),
00058         OLESTR("File could not be opened"),
00059         OLESTR("VERIFY has failed"),
00060         OLESTR("COMTHROW test exception throwed"),
00061 };
00062 
00063 LPOLESTR core_descs[] = 
00064 {
00065         OLESTR("Object is locked by another Core component"),
00066         OLESTR("Lock value in Storage is invalid"),
00067         OLESTR("Attribute is not found"),
00068         OLESTR("Meta object is not found"),
00069         OLESTR("Meta project is invalid"),
00070         OLESTR("Invalid response from Repository"),
00071         OLESTR("CoreProject - CoreMetaProject mismatch"),
00072         OLESTR("Object is deleted or unloaded (zombie)"),
00073         OLESTR("Invalid ValueType"),
00074         OLESTR("No active transaction"),
00075         OLESTR("Object already exists"),
00076         OLESTR("No Territory has been selected"),
00077         OLESTR("Object is not locked"),
00078         OLESTR("Invalid data in Repository"),
00079         OLESTR("Cannot delete Object, has nonempty collection"),
00080         OLESTR("Cannot resolve the connection string"),
00081         OLESTR("Invalid binary file storage"),
00082         OLESTR("Project has no name"),
00083 };
00084 
00085 LPOLESTR meta_descs[] = 
00086 {
00087         OLESTR("Invalid ATTVAL type"),
00088         OLESTR("MetaProject is not open"),
00089         OLESTR("Invalid Path"),
00090         OLESTR("Invalid MetaRef")
00091 };
00092 
00093 LPOLESTR parser_descs[] = 
00094 {
00095         OLESTR("Invalid DTD file"),
00096         OLESTR("Invalid GUID"),
00097         OLESTR("Invalid XML filename"),
00098         OLESTR("Invalid MGA object"),
00099         OLESTR("Invalid META object"),
00100         OLESTR("Too many passes while parsing the XML file"),
00101         OLESTR("Invalid long value in XML file")
00102 };
00103 
00104 void throw_com_error(HRESULT hr, LPCOLESTR desc)
00105 {
00106         ASSERT( desc != NULL );
00107 
00108         try
00109         {
00110                 CComObjPtr<ICreateErrorInfo> errorinfo;
00111                 COMTHROW( CreateErrorInfo(PutOut(errorinfo)) );
00112                 COMTHROW( errorinfo->SetDescription(const_cast<LPOLESTR>(desc)) );
00113                 COMTHROW( errorinfo->SetSource(OLESTR("GME")) );
00114 
00115                 CComObjPtr<IErrorInfo> errorinfo2;
00116                 COMTHROW( QueryInterface(errorinfo, errorinfo2) );
00117                 COMTHROW( SetErrorInfo(0, errorinfo2) );
00118 
00119                 throw _com_error(hr, errorinfo2, true);
00120         }
00121         catch(hresult_exception &)
00122         {
00123                 // do nothing
00124         }
00125 }
00126 
00127 void throw_last_com_error(HRESULT hr)
00128 {
00129         _bstr_t err;
00130         if (GetErrorInfo(err.GetAddress()))
00131         {
00132                 throw_com_error(hr, static_cast<const wchar_t*>(err));
00133         }
00134         else
00135         {
00136                 throw hresult_exception(hr);
00137         }
00138 }
00139 
00140 void SetErrorInfo(LPCOLESTR desc)
00141 {
00142         ASSERT( desc != NULL );
00143 
00144         try
00145         {
00146                 CComObjPtr<ICreateErrorInfo> errorinfo;
00147                 COMTHROW( CreateErrorInfo(PutOut(errorinfo)) );
00148                 COMTHROW( errorinfo->SetDescription(const_cast<LPOLESTR>(desc)) );
00149                 COMTHROW( errorinfo->SetSource(OLESTR("GME")) );
00150 
00151                 CComObjPtr<IErrorInfo> errorinfo2;
00152                 COMTHROW( QueryInterface(errorinfo, errorinfo2) );
00153                 COMTHROW( SetErrorInfo(0, errorinfo2) );
00154         }
00155         catch(hresult_exception &)
00156         {
00157                 // do nothing
00158         }
00159 }
00160 
00161 
00162 struct errtab {
00163         long code;
00164         LPOLESTR descr;
00165 };
00166 
00167 #include "..\Mga\MgaErr.c"
00168 
00169 #define MGAERRCODEBASE 0x87650000
00170 #define MGAERRCODESPAN 0x1000
00171 
00172 LPCOLESTR MgaGetErrorInfo(HRESULT hr) {
00173         if(hr >= MGAERRCODEBASE && hr < MGAERRCODEBASE + MGAERRCODESPAN) {
00174                 for(struct errtab const *hh = MgaErrTab; hh->code != 0; hh++) { 
00175                         if(hh->code == hr) {
00176                                 return hh->descr;
00177                         }
00178                 }
00179         }
00180         return NULL;
00181 }
00182 
00183 bool MgaSetErrorInfo(HRESULT hr) {
00184         LPCOLESTR mgaError = MgaGetErrorInfo(hr);
00185         if (mgaError)
00186         {
00187                 SetErrorInfo(mgaError);
00188                 return true;
00189         }
00190         return false;
00191 }
00192 
00193 void SetErrorInfo(HRESULT hr, LPOLESTR desc2)
00194 {
00195         ASSERT( sizeof(common_descs)/sizeof(LPOLESTR) == (E_COMMON_LAST-E_COMMON_FIRST+1) );
00196         ASSERT( sizeof(core_descs)/sizeof(LPOLESTR) == (E_CORE_LAST-E_CORE_FIRST+1) );
00197         ASSERT( sizeof(meta_descs)/sizeof(LPOLESTR) == (E_META_LAST-E_META_FIRST+1) );
00198         ASSERT( sizeof(parser_descs)/sizeof(LPOLESTR) == (E_PARSER_LAST-E_PARSER_FIRST+1) );
00199 
00200         LPOLESTR desc = NULL;
00201         if( E_COMMON_FIRST <= hr && hr <= E_COMMON_LAST ) desc = common_descs[hr - E_COMMON_FIRST];
00202         else if( E_CORE_FIRST <= hr && hr <= E_CORE_LAST ) desc = core_descs[hr - E_CORE_FIRST];
00203         else if( E_META_FIRST <= hr && hr <= E_META_LAST ) desc = meta_descs[hr - E_META_FIRST];
00204         else if( E_PARSER_FIRST <= hr && hr <= E_PARSER_LAST ) desc = parser_descs[hr - E_PARSER_FIRST];
00205 
00206         if( desc2 == NULL )
00207         {
00208                 if( desc != NULL )
00209                         SetErrorInfo(desc);
00210                 else if (hr >= MGAERRCODEBASE && hr < MGAERRCODEBASE + MGAERRCODESPAN)
00211                 {
00212                         MgaSetErrorInfo(hr);
00213                 }
00214         }
00215         else
00216         {
00217                 CComBSTR d(desc);
00218                 if( desc != NULL )
00219                         COMTHROW(d.Append(L" :"));
00220 
00221                 COMTHROW(d.Append(desc2));
00222                 SetErrorInfo(d);
00223         }
00224 }
00225 
00226 bool GetErrorInfo(BSTR *desc)
00227 {
00228         ASSERT( desc != NULL );
00229 
00230         try
00231         {
00232                 CComObjPtr<IErrorInfo> errinfo;
00233                 COMTHROW( GetErrorInfo(0, PutOut(errinfo)) );
00234                 ASSERT( errinfo != NULL );
00235 
00236                 if( errinfo) COMTHROW( errinfo->GetDescription(desc) );
00237         }
00238         catch(hresult_exception &)
00239         {
00240                 // do nothing
00241                 return false;
00242         }
00243         return true;
00244 }
00245 
00246 void GetErrorInfo(HRESULT hr, BSTR *p)
00247 {
00248         ASSERT( p != NULL );
00249 
00250         LPOLESTR desc = NULL;
00251         if( E_COMMON_FIRST <= hr && hr <= E_COMMON_LAST ) desc = common_descs[hr - E_COMMON_FIRST];
00252         else if( E_CORE_FIRST <= hr && hr <= E_CORE_LAST ) desc = core_descs[hr - E_CORE_FIRST];
00253         else if( E_META_FIRST <= hr && hr <= E_META_LAST ) desc = meta_descs[hr - E_META_FIRST];
00254         else if( E_PARSER_FIRST <= hr && hr <= E_PARSER_LAST ) desc = parser_descs[hr - E_PARSER_FIRST];
00255         
00256         if( desc != NULL )
00257         {
00258                 SysFreeString(*p);
00259                 *p = SysAllocString(desc);
00260         }
00261         else if (hr >= MGAERRCODEBASE && hr < MGAERRCODEBASE + MGAERRCODESPAN)
00262         {
00263                 LPCOLESTR mgaError = MgaGetErrorInfo(hr);
00264                 if (mgaError)
00265                         *p = SysAllocString(mgaError);
00266                 else
00267                         GetErrorInfo(E_FAIL, p);
00268         }
00269         else
00270         {
00271                 LPWSTR errorText = NULL;
00272                 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_ALLOCATE_BUFFER |FORMAT_MESSAGE_IGNORE_INSERTS,  
00273                    NULL, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&errorText, 0, NULL);
00274                 if (errorText != NULL) {
00275                         SysFreeString(*p);
00276                         *p = SysAllocString(errorText);
00277                         LocalFree(errorText);
00278                 } else {
00279                         if (!GetErrorInfo(p))
00280                         {
00281                                 GetErrorInfo(E_FAIL, p);
00282                         }
00283                 }
00284         }
00285 }