| 114 | PyObject* exc_value() const { return exc_value_.obj(); } |
| 115 | |
| 116 | static std::shared_ptr<PythonErrorDetail> FromPyError() { |
| 117 | PyObject* exc_type = nullptr; |
| 118 | PyObject* exc_value = nullptr; |
| 119 | PyObject* exc_traceback = nullptr; |
| 120 | |
| 121 | PyErr_Fetch(&exc_type, &exc_value, &exc_traceback); |
| 122 | PyErr_NormalizeException(&exc_type, &exc_value, &exc_traceback); |
| 123 | ARROW_CHECK(exc_type) |
| 124 | << "PythonErrorDetail::FromPyError called without a Python error set"; |
| 125 | ARROW_DCHECK(PyType_Check(exc_type)); |
| 126 | ARROW_DCHECK(exc_value); // Ensured by PyErr_NormalizeException, double-check |
| 127 | if (exc_traceback == nullptr) { |
| 128 | // Needed by PyErr_Restore() |
| 129 | Py_INCREF(Py_None); |
| 130 | exc_traceback = Py_None; |
| 131 | } |
| 132 | |
| 133 | std::shared_ptr<PythonErrorDetail> detail(new PythonErrorDetail); |
| 134 | detail->exc_type_.reset(exc_type); |
| 135 | detail->exc_value_.reset(exc_value); |
| 136 | detail->exc_traceback_.reset(exc_traceback); |
| 137 | return detail; |
| 138 | } |
| 139 | |
| 140 | protected: |
| 141 | Result<std::string> FormatImpl() const { |