/* * errors.c * Copyright (C) 2015 Kovid Goyal * * Distributed under terms of the GPL3 license. */ #include "dukpy.h" static int copy_error_attr(PyObject *obj, const char* name, PyObject *dest) { PyObject *value = NULL; if (!PyObject_HasAttrString(obj, name)) return 0; value = PyObject_GetAttrString(obj, name); if (value == NULL) return 0; if (PyDict_SetItemString(dest, name, value) != 0) {Py_DECREF(value); return 0;} Py_DECREF(value); return 1; } void set_dukpy_error(PyObject *obj) { PyObject *err = NULL, *iterator = NULL, *item = NULL; if (Py_TYPE(obj) == &DukObject_Type) { err = PyDict_New(); if (err == NULL) { PyErr_NoMemory(); return; } // Look for the common error object properties that may be up the prototype chain if (!copy_error_attr(obj, "name", err)) { Py_DECREF(err); return; } if (!copy_error_attr(obj, "message", err)) { Py_DECREF(err); return; } if (!copy_error_attr(obj, "fileName", err)) { Py_DECREF(err); return; } if (!copy_error_attr(obj, "lineNumber", err)) { Py_DECREF(err); return; } if (!copy_error_attr(obj, "stack", err)) { Py_DECREF(err); return; } // Now copy over own properties iterator = PyObject_CallMethod(obj, "items", NULL); if (iterator == NULL) { Py_DECREF(err); return; } while ((item = PyIter_Next(iterator))) { PyDict_SetItem(err, PyTuple_GET_ITEM(item, 0), PyTuple_GET_ITEM(item, 1)); Py_DECREF(item); } PyErr_SetObject(JSError, err); Py_DECREF(err); Py_DECREF(iterator); } else PyErr_SetObject(JSError, obj); }