Skip to content

Commit 0eed2f2

Browse files
committed
Add proper error output to console
1 parent 5ff5254 commit 0eed2f2

File tree

2 files changed

+92
-26
lines changed

2 files changed

+92
-26
lines changed

src/module.cpp

Lines changed: 88 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ namespace py3lm {
12671267
Py_DECREF(argTuple);
12681268
}
12691269
if (processResult == ParamProcess::ErrorWithException) {
1270-
PyErr_Print();
1270+
g_py3lm.LogError();
12711271
}
12721272

12731273
SetFallbackReturn(method.GetReturnType().GetType(), ret);
@@ -1284,7 +1284,7 @@ namespace py3lm {
12841284
}
12851285

12861286
if (!result) {
1287-
PyErr_Print();
1287+
g_py3lm.LogError();
12881288

12891289
SetFallbackReturn(method.GetReturnType().GetType(), ret);
12901290

@@ -1295,7 +1295,7 @@ namespace py3lm {
12951295
if (!PyTuple_CheckExact(result)) {
12961296
PyErr_SetString(PyExc_TypeError, "Returned value not tuple");
12971297

1298-
PyErr_Print();
1298+
g_py3lm.LogError();
12991299

13001300
Py_DECREF(result);
13011301

@@ -1308,7 +1308,7 @@ namespace py3lm {
13081308
const std::string error(std::format("Returned tuple wrong size {}, expected {}", tupleSize, static_cast<Py_ssize_t>(1 + refParamsCount)));
13091309
PyErr_SetString(PyExc_TypeError, error.c_str());
13101310

1311-
PyErr_Print();
1311+
g_py3lm.LogError();
13121312

13131313
Py_DECREF(result);
13141314

@@ -1329,7 +1329,7 @@ namespace py3lm {
13291329
if (!SetRefParam(PyTuple_GET_ITEM(result, Py_ssize_t{ 1 + k }), paramType, params, index)) {
13301330
// SetRefParam may set error
13311331
if (PyErr_Occurred()) {
1332-
PyErr_Print();
1332+
g_py3lm.LogError();
13331333
}
13341334
}
13351335
++k;
@@ -1341,7 +1341,7 @@ namespace py3lm {
13411341

13421342
if (!SetReturn(returnObject, method.GetReturnType(), ret)) {
13431343
if (PyErr_Occurred()) {
1344-
PyErr_Print();
1344+
g_py3lm.LogError();
13451345
}
13461346

13471347
SetFallbackReturn(method.GetReturnType().GetType(), ret);
@@ -2526,68 +2526,86 @@ namespace py3lm {
25262526

25272527
PyObject* const plugifyPluginModuleName = PyUnicode_DecodeFSDefault("plugify.plugin");
25282528
if (!plugifyPluginModuleName) {
2529-
PyErr_Print();
2529+
LogError();
25302530
return ErrorData{ "Failed to allocate plugify.plugin module string" };
25312531
}
25322532

25332533
PyObject* const plugifyPluginModule = PyImport_Import(plugifyPluginModuleName);
25342534
Py_DECREF(plugifyPluginModuleName);
25352535
if (!plugifyPluginModule) {
2536-
PyErr_Print();
2536+
LogError();
25372537
return ErrorData{ "Failed to import plugify.plugin python module" };
25382538
}
25392539

25402540
_PluginTypeObject = PyObject_GetAttrString(plugifyPluginModule, "Plugin");
25412541
if (!_PluginTypeObject) {
25422542
Py_DECREF(plugifyPluginModule);
2543-
PyErr_Print();
2543+
LogError();
25442544
return ErrorData{ "Failed to find plugify.plugin.Plugin type" };
25452545
}
25462546
_PluginInfoTypeObject = PyObject_GetAttrString(plugifyPluginModule, "PluginInfo");
25472547
if (!_PluginInfoTypeObject) {
25482548
Py_DECREF(plugifyPluginModule);
2549-
PyErr_Print();
2549+
LogError();
25502550
return ErrorData{ "Failed to find plugify.plugin.PluginInfo type" };
25512551
}
25522552

25532553
_Vector2TypeObject = PyObject_GetAttrString(plugifyPluginModule, "Vector2");
25542554
if (!_Vector2TypeObject) {
25552555
Py_DECREF(plugifyPluginModule);
2556-
PyErr_Print();
2556+
LogError();
25572557
return ErrorData{ "Failed to find plugify.plugin.Vector2 type" };
25582558
}
25592559
_Vector3TypeObject = PyObject_GetAttrString(plugifyPluginModule, "Vector3");
25602560
if (!_Vector3TypeObject) {
25612561
Py_DECREF(plugifyPluginModule);
2562-
PyErr_Print();
2562+
LogError();
25632563
return ErrorData{ "Failed to find plugify.plugin.Vector3 type" };
25642564
}
25652565
_Vector4TypeObject = PyObject_GetAttrString(plugifyPluginModule, "Vector4");
25662566
if (!_Vector4TypeObject) {
25672567
Py_DECREF(plugifyPluginModule);
2568-
PyErr_Print();
2568+
LogError();
25692569
return ErrorData{ "Failed to find plugify.plugin.Vector4 type" };
25702570
}
25712571
_Matrix4x4TypeObject = PyObject_GetAttrString(plugifyPluginModule, "Matrix4x4");
25722572
if (!_Matrix4x4TypeObject) {
25732573
Py_DECREF(plugifyPluginModule);
2574-
PyErr_Print();
2574+
LogError();
25752575
return ErrorData{ "Failed to find plugify.plugin.Matrix4x4 type" };
25762576
}
25772577

25782578
Py_DECREF(plugifyPluginModule);
25792579

25802580
_ppsModule = PyImport_ImportModule("plugify.pps");
25812581
if (!_ppsModule) {
2582-
PyErr_Print();
2582+
LogError();
25832583
return ErrorData{ "Failed to import plugify.pps python module" };
25842584
}
25852585

2586+
_tracebackModule = PyImport_ImportModule("traceback");
2587+
if (!_tracebackModule) {
2588+
LogError();
2589+
return ErrorData{ "Failed to import traceback python module" };
2590+
}
2591+
_formatException = PyObject_GetAttrString(_tracebackModule, "format_exception");
2592+
if (!_formatException) {
2593+
return ErrorData{ "Failed to import traceback.format_exception python module" };
2594+
}
2595+
25862596
return InitResultData{};
25872597
}
25882598

25892599
void Python3LanguageModule::Shutdown() {
2590-
if (Py_IsInitialized()) {
2600+
if (Py_IsInitialized()) {
2601+
if (_formatException) {
2602+
Py_DECREF(_formatException);
2603+
}
2604+
2605+
if (_tracebackModule) {
2606+
Py_DECREF(_tracebackModule);
2607+
}
2608+
25912609
if (_ppsModule) {
25922610
Py_DECREF(_ppsModule);
25932611
}
@@ -2635,6 +2653,8 @@ namespace py3lm {
26352653

26362654
Py_Finalize();
26372655
}
2656+
_formatException = nullptr;
2657+
_tracebackModule = nullptr;
26382658
_ppsModule = nullptr;
26392659
_Vector2TypeObject = nullptr;
26402660
_Vector3TypeObject = nullptr;
@@ -2711,7 +2731,7 @@ namespace py3lm {
27112731

27122732
PyObject* const pluginModule = PyImport_ImportModule(moduleName.c_str());
27132733
if (!pluginModule) {
2714-
PyErr_Print();
2734+
LogError();
27152735
return ErrorData{ std::format("Failed to import {} module", moduleName) };
27162736
}
27172737

@@ -2725,7 +2745,7 @@ namespace py3lm {
27252745
if (!pluginClass) {
27262746
Py_DECREF(classNameString);
27272747
Py_DECREF(pluginModule);
2728-
PyErr_Print();
2748+
LogError();
27292749
return ErrorData{ "Failed to find plugin class" };
27302750
}
27312751

@@ -2734,7 +2754,7 @@ namespace py3lm {
27342754
Py_DECREF(pluginClass);
27352755
Py_DECREF(classNameString);
27362756
Py_DECREF(pluginModule);
2737-
PyErr_Print();
2757+
LogError();
27382758
return ErrorData{ std::format("Class '{}' not subclass of Plugin", className) };
27392759
}
27402760

@@ -2743,7 +2763,7 @@ namespace py3lm {
27432763
if (!pluginInstance) {
27442764
Py_DECREF(classNameString);
27452765
Py_DECREF(pluginModule);
2746-
PyErr_Print();
2766+
LogError();
27472767
return ErrorData{ "Failed to create plugin instance" };
27482768
}
27492769

@@ -2764,7 +2784,7 @@ namespace py3lm {
27642784
if (!pluginInfo) {
27652785
Py_DECREF(pluginInstance);
27662786
Py_DECREF(pluginModule);
2767-
PyErr_Print();
2787+
LogError();
27682788
return ErrorData{ "Failed to save instance: plugin info not constructed" };
27692789
}
27702790

@@ -2773,7 +2793,7 @@ namespace py3lm {
27732793
if (resultCode != 0) {
27742794
Py_DECREF(pluginInstance);
27752795
Py_DECREF(pluginModule);
2776-
PyErr_Print();
2796+
LogError();
27772797
return ErrorData{ "Failed to save instance: assignment fail" };
27782798
}
27792799

@@ -3396,15 +3416,15 @@ namespace py3lm {
33963416

33973417
PyObject* const nameString = PyUnicode_DecodeFSDefault(name.c_str());
33983418
if (!nameString) {
3399-
PyErr_Print();
3419+
LogError();
34003420
_provider->Log(std::format("[py3lm] {}: failed to allocate name string", context), Severity::Error);
34013421
return;
34023422
}
34033423

34043424
if (PyObject_HasAttr(pluginData._instance, nameString)) {
34053425
PyObject* const returnObject = PyObject_CallMethodNoArgs(pluginData._instance, nameString);
34063426
if (!returnObject) {
3407-
PyErr_Print();
3427+
LogError();
34083428
_provider->Log(std::format("[py3lm] {}: call '{}' failed", context, name), Severity::Error);
34093429
}
34103430
}
@@ -3414,7 +3434,50 @@ namespace py3lm {
34143434
return;
34153435
}
34163436

3417-
void Python3LanguageModule::LogFatal(const std::string& msg) const {
3437+
void Python3LanguageModule::LogError() const {
3438+
PyObject* ptype = nullptr;
3439+
PyObject* pvalue = nullptr;
3440+
PyObject* ptraceback = nullptr;
3441+
PyErr_Fetch(&ptype, &pvalue, &ptraceback);
3442+
std::string result;
3443+
if (!pvalue) {
3444+
Py_INCREF(Py_None);
3445+
pvalue = Py_None;
3446+
}
3447+
if (!ptraceback) {
3448+
Py_INCREF(Py_None);
3449+
ptraceback = Py_None;
3450+
}
3451+
PyErr_NormalizeException(&ptype, &pvalue, &ptraceback);
3452+
PyObject* strList = PyObject_CallFunctionObjArgs(_formatException, ptype, pvalue, ptraceback, nullptr);
3453+
Py_DECREF(ptype);
3454+
Py_DECREF(pvalue);
3455+
Py_DECREF(ptraceback);
3456+
if (!strList) {
3457+
_provider->Log("Couldn't get exact error message", Severity::Error);
3458+
return;
3459+
}
3460+
3461+
if (PySequence_Check(strList)) {
3462+
PyObject* strList_fast = PySequence_Fast(strList, "Shouldn't happen (1)");
3463+
PyObject** items = PySequence_Fast_ITEMS(strList_fast);
3464+
Py_ssize_t L = PySequence_Fast_GET_SIZE(strList_fast);
3465+
for (Py_ssize_t i = 0; i < L; ++i) {
3466+
PyObject* utf8 = PyUnicode_AsUTF8String(items[i]);
3467+
result += PyBytes_AsString(utf8);
3468+
Py_DECREF(utf8);
3469+
}
3470+
Py_DECREF(strList_fast);
3471+
} else {
3472+
result = "Can't get exact error message";
3473+
}
3474+
3475+
Py_DECREF(strList);
3476+
3477+
_provider->Log(result, Severity::Error);
3478+
}
3479+
3480+
void Python3LanguageModule::LogFatal(std::string_view msg) const {
34183481
_provider->Log(msg, Severity::Fatal);
34193482
}
34203483

src/module.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ namespace py3lm {
5656
std::optional<plugify::Vector4> Vector4ValueFromObject(PyObject* object);
5757
PyObject* CreateMatrix4x4Object(const plugify::Matrix4x4& matrix);
5858
std::optional<plugify::Matrix4x4> Matrix4x4ValueFromObject(PyObject* object);
59-
void LogFatal(const std::string& msg) const;
59+
void LogFatal(std::string_view msg) const;
60+
void LogError() const;
6061

6162
private:
6263
PyObject* FindPythonMethod(plugify::MemAddr addr) const;
@@ -80,6 +81,8 @@ namespace py3lm {
8081
PyObject* _Vector4TypeObject = nullptr;
8182
PyObject* _Matrix4x4TypeObject = nullptr;
8283
PyObject* _ppsModule = nullptr;
84+
PyObject* _tracebackModule = nullptr;
85+
PyObject* _formatException = nullptr;
8386
std::vector<std::vector<PyMethodDef>> _moduleMethods;
8487
std::vector<std::unique_ptr<PyModuleDef>> _moduleDefinitions;
8588
struct JitHolder {

0 commit comments

Comments
 (0)