forked from Distributive-Network/PythonMonkey
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathExceptionType.cc
More file actions
51 lines (40 loc) · 2.09 KB
/
ExceptionType.cc
File metadata and controls
51 lines (40 loc) · 2.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#include "include/modules/pythonmonkey/pythonmonkey.hh"
#include "include/setSpiderMonkeyException.hh"
#include "include/ExceptionType.hh"
#include <jsapi.h>
#include <js/Exception.h>
#include <Python.h>
ExceptionType::ExceptionType(PyObject *object) : PyType(object) {}
ExceptionType::ExceptionType(JSContext *cx, JS::HandleObject error) {
// Convert the JS Error object to a Python string
JS::RootedValue errValue(cx, JS::ObjectValue(*error)); // err
JS::RootedObject errStack(cx, JS::ExceptionStackOrNull(error)); // err.stack
PyObject *errStr = getExceptionString(cx, JS::ExceptionStack(cx, errValue, errStack));
// Construct a new SpiderMonkeyError python object
// pyObject = SpiderMonkeyError(errStr)
#if PY_VERSION_HEX >= 0x03090000
pyObject = PyObject_CallOneArg(SpiderMonkeyError, errStr); // _PyErr_CreateException, https://github.com/python/cpython/blob/3.9/Python/errors.c#L100
#else
pyObject = PyObject_CallFunction(SpiderMonkeyError, "O", errStr); // PyObject_CallOneArg is not available in Python < 3.9
#endif
Py_XDECREF(errStr);
}
// TODO (Tom Tang): preserve the original Python exception object somewhere in the JS obj for lossless two-way conversion
JSObject *ExceptionType::toJsError(JSContext *cx) {
PyObject *pyErrType = PyObject_Type(pyObject);
const char *pyErrTypeName = _PyType_Name((PyTypeObject *)pyErrType);
PyObject *pyErrMsg = PyObject_Str(pyObject);
// TODO (Tom Tang): Convert Python traceback and set it as the `stack` property on JS Error object
// PyObject *traceback = PyException_GetTraceback(pyObject);
std::stringstream msgStream;
msgStream << "Python " << pyErrTypeName << ": " << PyUnicode_AsUTF8(pyErrMsg);
std::string msg = msgStream.str();
JS::RootedValue rval(cx);
JS::RootedObject stack(cx);
JS::RootedString filename(cx, JS_NewStringCopyZ(cx, "[python code]"));
JS::RootedString message(cx, JS_NewStringCopyZ(cx, msg.c_str()));
JS::CreateError(cx, JSExnType::JSEXN_ERR, stack, filename, 0, 0, nullptr, message, JS::NothingHandleValue, &rval);
Py_DECREF(pyErrType);
Py_DECREF(pyErrMsg);
return rval.toObjectOrNull();
}