MCPcopy Create free account
hub / github.com/Distributive-Network/PythonMonkey / promiseRejectionTracker

Method promiseRejectionTracker

src/JobQueue.cc:130–165  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

128}
129
130void JobQueue::promiseRejectionTracker(JSContext *cx,
131 bool mutedErrors,
132 JS::HandleObject promise,
133 JS::PromiseRejectionHandlingState state,
134 [[maybe_unused]] void *privateData) {
135
136 // We only care about unhandled Promises
137 if (state != JS::PromiseRejectionHandlingState::Unhandled) {
138 return;
139 }
140 // If the `mutedErrors` option is set to True in `pm.eval`, eval errors or unhandled rejections should be ignored.
141 if (mutedErrors) {
142 return;
143 }
144
145 // Test if there's no user-defined (or pmjs defined) exception handler on the Python event-loop
146 PyEventLoop loop = PyEventLoop::getRunningLoop();
147 if (!loop.initialized()) return;
148 PyObject *customHandler = PyObject_GetAttrString(loop._loop, "_exception_handler"); // see https://github.com/python/cpython/blob/v3.9.16/Lib/asyncio/base_events.py#L1782
149 if (customHandler == Py_None) { // we only have the default exception handler
150 // Set an exception handler to the event-loop
151 PyObject *pmModule = PyImport_ImportModule("pythonmonkey");
152 PyObject *exceptionHandler = PyObject_GetAttrString(pmModule, "simpleUncaughtExceptionHandler");
153 PyObject_CallMethod(loop._loop, "set_exception_handler", "O", exceptionHandler);
154 Py_DECREF(pmModule);
155 Py_DECREF(exceptionHandler);
156 }
157 Py_DECREF(customHandler);
158
159 // Go ahead and send this unhandled Promise rejection to the exception handler on the Python event-loop
160 PyObject *pyFuture = PromiseType::getPyObject(cx, promise); // ref count == 2
161 // Unhandled Future object calls the event-loop exception handler in its destructor (the `__del__` magic method)
162 // See https://github.com/python/cpython/blob/v3.9.16/Lib/asyncio/futures.py#L108
163 // or https://github.com/python/cpython/blob/v3.9.16/Modules/_asynciomodule.c#L1457-L1467 (It will actually use the C module by default, see futures.py#L417-L423)
164 Py_DECREF(pyFuture); // decreasing the reference count from 2 to 1, leaving one for the `onResolved` callback in `PromiseType::getPyObject`, which will be called very soon and clean up the reference
165}
166
167void JobQueue::queueFinalizationRegistryCallback(JSFunction *callback) {
168 mozilla::Unused << finalizationRegistryCallbacks->append(callback);

Callers

nothing calls this directly

Calls 1

initializedMethod · 0.80

Tested by

no test coverage detected