theKernel 10.0 NHI1 - theKernel - theLink - theConfig - theSq3Lite - theCompiler - theBrain - theGuard
c - tcl - py - jv - cc
Loading...
Searching...
No Matches
MkExceptionC_PY_API

MkExceptionC - The default-exception of the Programming-Language-Micro-Kernel (PLMK)More...

+ Collaboration diagram for MkExceptionC_PY_API:

Functions

void py_mkkernel_MkExceptionC_Raise (OT_Prefix_ARGS MK_MNGN const expobj, MK_STRN const doc, MK_STRN const callfunc, MK_I32 callline)
 C-API: MkExceptionRaise - convert an MkErrorC into a Target-Programming-Language (TPL) exception …
 
MK_ERR py_mkkernel_MkExceptionC_Set (OT_Prefix_ARGS MK_MNG const expobj, MK_EXP const exception, MK_STRN const callfunc)
 C-API: MkExceptionCatch - convert an Target-Programming-Language (TPL) exception into an MkErrorC
 

Detailed Description

MkExceptionC - The default-exception of the Programming-Language-Micro-Kernel (PLMK)

The Programming-Language-Micro-Kernel (PLMK) provide with MkErrorC a complete error-handling with focus to support the "C" Programming-Language. The support include catch, raise, signal and attributes. In addition every Target-Programming-Language (TPL) add their own error-handling and the purpose of MkExceptionC is to integrate the MkErrorC into the Target-Programming-Language (TPL).

The default-exception MkExceptionC is used to connect the MkErrorC with the Target-Programming-Language (TPL) error-object.

The implementation of an exception depends heavily on the Target-Programming-Language (TPL), starting with no exception at all, for example. C, an exception as a class object, or as an exception as a global attribute.

Attention

Function Documentation

◆ py_mkkernel_MkExceptionC_Raise()

void py_mkkernel_MkExceptionC_Raise ( OT_Prefix_ARGS MK_MNGN const expobj,
MK_STRN const doc,
MK_STRN const callfunc,
MK_I32 callline )

C-API: MkExceptionRaise - convert an MkErrorC into a Target-Programming-Language (TPL) exception …

Parameters
[in]expobjThe LibMsgqueObject used to personalize the exception/error (will be validated first)
[in]callfunca user-defined postfix to identify the calling function or the environment (default=name-of-function)
[in]calllinethe number of the line the call take place (e.g. LINE)
[in]docdocumentation string

Definition at line 26 of file MkExceptionC_py.c.

33{
34 PyErr_Clear();
35 MK_ERR err = MkErrorFORMAT_1M(expobj);
36 MkErrorStackFormat(err,doc,callfunc,callline);
37 PyObject *stackO = NULL; // buffer hold all the current stack frame
38 for (int lvl = 0; MK(Get_Call_Stack)(MK_RT_CALL err, lvl, &stackO); lvl++) {
39 //printI(lvl);
40 }
41 Py_CLEAR(stackO);
42 MK_ERR newerr = MkErrCheck(expobj) && expobj != err ? (MK_ERR)expobj : MkErrorDup(err);
43 PyObject* errO = OT_TMP_ERR_OBJ(newerr);
44 PyErr_SetObject(NS(MkKernelThreadState).MkExceptionC, errO);
45 Py_CLEAR(errO);
46 // TODO difference between python and tcl MkErrorReset_1M(expobj) versa MkErrorReset_1(err)
47 if (expobj) MkErrorReset_1M(expobj);
48}
struct MkErrorS * MK_ERR
class-shortcut for struct MkErrorS *, all shortcut using the XX_YYY syntax (only for public API) …
bool MkErrCheck(MK_MNGN mng)
check MkErrorS -> MkObjectS::signature …
#define MkErrorStackFormat(...)
#define MkErrorReset_1M(err)
#define MkErrorFORMAT_1M(m)
#define MkErrorDup(...)
#define MK_RT_CALL
The data-type to store and handle the error-condition …

◆ py_mkkernel_MkExceptionC_Set()

MK_ERR py_mkkernel_MkExceptionC_Set ( OT_Prefix_ARGS MK_MNG const expobj,
MK_EXP const exception,
MK_STRN const callfunc )

C-API: MkExceptionCatch - convert an Target-Programming-Language (TPL) exception into an MkErrorC

Parameters
[in]expobjThe LibMsgqueObject used to personalize the exception/error (will be validated first)
[in]exceptionthe exception object from Python, if None the global exception object is used
[in]callfunca user-defined postfix to identify the calling function or the environment (default=name-of-function)
Returns
the MkErrorC created with data from exception

Definition at line 51 of file MkExceptionC_py.c.

56 {
57 //MQ_CTX context = MqCtx(fmtObj);
58
59 PyObject *errO = (PyObject*) exception;
60
61 MK_ERR err = MkErrorFORMAT_1M(expobj);
62 PyObject *typeO = NULL, *valueO=NULL, *tbO = NULL;
63
64 if (errO == Py_None || errO == NULL) {
65 valueO = PyErr_GetRaisedException();
66 if (valueO == NULL) {
67 MkErrorSetC(err,"unspecified error",callfunc,1);
68 return err;
69 }
70 typeO = Py_NewRef(Py_TYPE(valueO));
71 } else {
72 typeO = Py_NewRef(Py_TYPE(errO));
73 valueO = Py_NewRef(errO);
74 }
75 tbO = PyException_GetTraceback(valueO);
76
77 {
78 PyObject *valO = NULL ;
79
80 // step 1. - is it an error?
81 if (typeO == Py_None || typeO == NULL) {
82 MkErrorSetC (err, "No active exception to reraise", callfunc, -1);
83
84 // step 2. - is it an MQ error?
85 } else if (PyErr_GivenExceptionMatches(typeO,NS(MkKernelThreadState).MkExceptionC)) {
86 MK_ERR newerr = NULL;
87 while (true) {
88 if (PyObject_TypeCheck(valueO,&NS(MkErrorCR))) {
89 newerr = MkErr(((MkErrorC_Obj*)errO)->hdl);
90 } else if (PyObject_TypeCheck(valueO,(PyTypeObject*)PyExc_BaseException)) {
91 PyObject *tupO = ((PyBaseExceptionObject*)valueO)->args;
92 if (tupO == NULL || !PyTuple_Check(tupO)) break;
93 PyObject *errO = PyTuple_GetItem(tupO, 0);
94 if (errO == NULL) break;
95 if (PyObject_TypeCheck(errO,&NS(MkErrorCR))) {
96 newerr = MkErr(((MkErrorC_Obj*)errO)->hdl);
97 }
98 }
99 break;
100 }
101 if (newerr) {
102 MkErrorSetE (err, newerr);
103 } else {
104 MkErrorSetC (err, "No active exception value object to reraise", callfunc, -1);
105 }
106
107 // step 3. - is it an PYTHON error?
108 } else if (valueO) {
109 PyObject *tmod = NULL, *strO = NULL, *lstO = NULL;
110 LngErrorCheckNT(end1, tmod = PyImport_ImportModule("traceback"));
111 if (tbO) {
112 LngErrorCheckNT(end1, lstO = PyObject_CallMethod(tmod, "format_exception", "OOO", typeO, valueO, tbO));
113 } else {
114 LngErrorCheckNT(end1, lstO = PyObject_CallMethod(tmod, "format_exception_only", "OO", typeO, valueO));
115 }
116 LngErrorCheckNT(end1, strO = PyC2O(""));
117 LngErrorCheckNT(end1, valO = PyObject_CallMethod(strO, "join", "O", lstO));
118end1:
119 Py_CLEAR(tmod);
120 Py_CLEAR(lstO);
121 Py_CLEAR(strO);
122 if (valO != NULL && PyUnicode_Check(valO)) {
123 PyObject *strO=NULL;
124 char *utf8=NULL;
125 Py_ssize_t size;
126
127 LngErrorCheckNT(end2, strO = PyObject_Str(valO));
128 utf8 = (char*)PyUnicode_AsUTF8AndSize(strO,&size);
129 if (utf8==NULL) goto end2;
130 // delete newline
131 if (utf8[size-1]==10) utf8[size-1]=0;
132 MkErrorSetC(err, utf8, callfunc, -1);
133
134//printXLV(context, "11111 -> MkErrorTLS.server_ctx=%p, MkErrorTLS.client_ctx=%p\n",
135// MkErrorTLS.server_ctx, MkErrorTLS.client_ctx);
136
137end2:
138 Py_CLEAR(strO);
139 }
141 MkErrorSetV(err, callfunc, -1, "%s: python error", PyExceptionClass_Name(typeO));
142 }
143 }
144
145 Py_CLEAR(tbO);
146 Py_CLEAR(typeO);
147 Py_CLEAR(valueO);
148 if (PyErr_Occurred()) PyErr_Clear();
149 return err;
150}
MK_ERR MkErr(MK_MNG mng)
cast a unknown-object into an MkErrorS pointer or NULL if not possible
#define MkErrorGetCode_0E()
#define MkErrorSetC(...)
#define MkErrorSetV(...)
#define MkErrorSetE(...)
@ MK_ERROR
(persistent) raise an error-event, the calling-fucntion is interrupted.