Generically fills an EXCEP_INFO. The scode in the EXCEPINFO is the HRESULT as nominated by the user.
| 62 | // Generically fills an EXCEP_INFO. The scode in the EXCEPINFO |
| 63 | // is the HRESULT as nominated by the user. |
| 64 | void PyCom_ExcepInfoFromPyException(EXCEPINFO *pExcepInfo) |
| 65 | { |
| 66 | // If the caller did not provide a valid exception info, get out now! |
| 67 | if (pExcepInfo==NULL) { |
| 68 | PyErr_Clear(); // must leave Python in a clean state. |
| 69 | return; |
| 70 | } |
| 71 | PyObject *exception, *v, *tb; |
| 72 | PyErr_Fetch(&exception, &v, &tb); |
| 73 | if (PyCom_ExcepInfoFromPyObject(v, pExcepInfo, NULL)) |
| 74 | { |
| 75 | // done. |
| 76 | } |
| 77 | else |
| 78 | { |
| 79 | memset(pExcepInfo, 0, sizeof(EXCEPINFO)); |
| 80 | // Clear the exception raised by PyCom_ExcepInfoFromPyObject, |
| 81 | // not the one we are interested in! |
| 82 | PyErr_Clear(); |
| 83 | // Not a special exception object - do the best we can. |
| 84 | char *szBaseMessage = "Unexpected Python Error: "; |
| 85 | char *szException = GetPythonTraceback(exception, v, tb); |
| 86 | size_t len = strlen(szBaseMessage) + strlen(szException) + 1; |
| 87 | char *tempBuf = new char[len]; |
| 88 | if (tempBuf) { |
| 89 | snprintf(tempBuf, len, "%s%s", szBaseMessage, szException); |
| 90 | pExcepInfo->bstrDescription = PyWin_String_AsBstr(tempBuf); |
| 91 | delete [] tempBuf; |
| 92 | } else |
| 93 | pExcepInfo->bstrDescription = SysAllocString(L"memory error allocating exception buffer!"); |
| 94 | pExcepInfo->bstrSource = SysAllocString(L"Python COM Server Internal Error"); |
| 95 | |
| 96 | // Map some well known exceptions to specific HRESULTs |
| 97 | // Note: v can be NULL. This can happen via PyErr_SetNone(). |
| 98 | // e.g.: KeyboardInterrupt |
| 99 | if (PyErr_GivenExceptionMatches(exception, PyExc_MemoryError)) |
| 100 | pExcepInfo->scode = E_OUTOFMEMORY; |
| 101 | else |
| 102 | // Any other common Python exceptions we should map? |
| 103 | pExcepInfo->scode = E_FAIL; |
| 104 | } |
| 105 | Py_XDECREF(exception); |
| 106 | Py_XDECREF(v); |
| 107 | Py_XDECREF(tb); |
| 108 | PyErr_Clear(); |
| 109 | } |
| 110 | |
| 111 | static BOOL PyCom_ExcepInfoFromServerExceptionInstance(PyObject *v, EXCEPINFO *pExcepInfo) |
| 112 | { |
no test coverage detected