@@ -1267,7 +1267,7 @@ namespace py3lm {
1267
1267
Py_DECREF (argTuple);
1268
1268
}
1269
1269
if (processResult == ParamProcess::ErrorWithException) {
1270
- PyErr_Print ();
1270
+ g_py3lm. LogError ();
1271
1271
}
1272
1272
1273
1273
SetFallbackReturn (method.GetReturnType ().GetType (), ret);
@@ -1284,7 +1284,7 @@ namespace py3lm {
1284
1284
}
1285
1285
1286
1286
if (!result) {
1287
- PyErr_Print ();
1287
+ g_py3lm. LogError ();
1288
1288
1289
1289
SetFallbackReturn (method.GetReturnType ().GetType (), ret);
1290
1290
@@ -1295,7 +1295,7 @@ namespace py3lm {
1295
1295
if (!PyTuple_CheckExact (result)) {
1296
1296
PyErr_SetString (PyExc_TypeError, " Returned value not tuple" );
1297
1297
1298
- PyErr_Print ();
1298
+ g_py3lm. LogError ();
1299
1299
1300
1300
Py_DECREF (result);
1301
1301
@@ -1308,7 +1308,7 @@ namespace py3lm {
1308
1308
const std::string error (std::format (" Returned tuple wrong size {}, expected {}" , tupleSize, static_cast <Py_ssize_t>(1 + refParamsCount)));
1309
1309
PyErr_SetString (PyExc_TypeError, error.c_str ());
1310
1310
1311
- PyErr_Print ();
1311
+ g_py3lm. LogError ();
1312
1312
1313
1313
Py_DECREF (result);
1314
1314
@@ -1329,7 +1329,7 @@ namespace py3lm {
1329
1329
if (!SetRefParam (PyTuple_GET_ITEM (result, Py_ssize_t{ 1 + k }), paramType, params, index)) {
1330
1330
// SetRefParam may set error
1331
1331
if (PyErr_Occurred ()) {
1332
- PyErr_Print ();
1332
+ g_py3lm. LogError ();
1333
1333
}
1334
1334
}
1335
1335
++k;
@@ -1341,7 +1341,7 @@ namespace py3lm {
1341
1341
1342
1342
if (!SetReturn (returnObject, method.GetReturnType (), ret)) {
1343
1343
if (PyErr_Occurred ()) {
1344
- PyErr_Print ();
1344
+ g_py3lm. LogError ();
1345
1345
}
1346
1346
1347
1347
SetFallbackReturn (method.GetReturnType ().GetType (), ret);
@@ -2526,68 +2526,86 @@ namespace py3lm {
2526
2526
2527
2527
PyObject* const plugifyPluginModuleName = PyUnicode_DecodeFSDefault (" plugify.plugin" );
2528
2528
if (!plugifyPluginModuleName) {
2529
- PyErr_Print ();
2529
+ LogError ();
2530
2530
return ErrorData{ " Failed to allocate plugify.plugin module string" };
2531
2531
}
2532
2532
2533
2533
PyObject* const plugifyPluginModule = PyImport_Import (plugifyPluginModuleName);
2534
2534
Py_DECREF (plugifyPluginModuleName);
2535
2535
if (!plugifyPluginModule) {
2536
- PyErr_Print ();
2536
+ LogError ();
2537
2537
return ErrorData{ " Failed to import plugify.plugin python module" };
2538
2538
}
2539
2539
2540
2540
_PluginTypeObject = PyObject_GetAttrString (plugifyPluginModule, " Plugin" );
2541
2541
if (!_PluginTypeObject) {
2542
2542
Py_DECREF (plugifyPluginModule);
2543
- PyErr_Print ();
2543
+ LogError ();
2544
2544
return ErrorData{ " Failed to find plugify.plugin.Plugin type" };
2545
2545
}
2546
2546
_PluginInfoTypeObject = PyObject_GetAttrString (plugifyPluginModule, " PluginInfo" );
2547
2547
if (!_PluginInfoTypeObject) {
2548
2548
Py_DECREF (plugifyPluginModule);
2549
- PyErr_Print ();
2549
+ LogError ();
2550
2550
return ErrorData{ " Failed to find plugify.plugin.PluginInfo type" };
2551
2551
}
2552
2552
2553
2553
_Vector2TypeObject = PyObject_GetAttrString (plugifyPluginModule, " Vector2" );
2554
2554
if (!_Vector2TypeObject) {
2555
2555
Py_DECREF (plugifyPluginModule);
2556
- PyErr_Print ();
2556
+ LogError ();
2557
2557
return ErrorData{ " Failed to find plugify.plugin.Vector2 type" };
2558
2558
}
2559
2559
_Vector3TypeObject = PyObject_GetAttrString (plugifyPluginModule, " Vector3" );
2560
2560
if (!_Vector3TypeObject) {
2561
2561
Py_DECREF (plugifyPluginModule);
2562
- PyErr_Print ();
2562
+ LogError ();
2563
2563
return ErrorData{ " Failed to find plugify.plugin.Vector3 type" };
2564
2564
}
2565
2565
_Vector4TypeObject = PyObject_GetAttrString (plugifyPluginModule, " Vector4" );
2566
2566
if (!_Vector4TypeObject) {
2567
2567
Py_DECREF (plugifyPluginModule);
2568
- PyErr_Print ();
2568
+ LogError ();
2569
2569
return ErrorData{ " Failed to find plugify.plugin.Vector4 type" };
2570
2570
}
2571
2571
_Matrix4x4TypeObject = PyObject_GetAttrString (plugifyPluginModule, " Matrix4x4" );
2572
2572
if (!_Matrix4x4TypeObject) {
2573
2573
Py_DECREF (plugifyPluginModule);
2574
- PyErr_Print ();
2574
+ LogError ();
2575
2575
return ErrorData{ " Failed to find plugify.plugin.Matrix4x4 type" };
2576
2576
}
2577
2577
2578
2578
Py_DECREF (plugifyPluginModule);
2579
2579
2580
2580
_ppsModule = PyImport_ImportModule (" plugify.pps" );
2581
2581
if (!_ppsModule) {
2582
- PyErr_Print ();
2582
+ LogError ();
2583
2583
return ErrorData{ " Failed to import plugify.pps python module" };
2584
2584
}
2585
2585
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
+
2586
2596
return InitResultData{};
2587
2597
}
2588
2598
2589
2599
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
+
2591
2609
if (_ppsModule) {
2592
2610
Py_DECREF (_ppsModule);
2593
2611
}
@@ -2635,6 +2653,8 @@ namespace py3lm {
2635
2653
2636
2654
Py_Finalize ();
2637
2655
}
2656
+ _formatException = nullptr ;
2657
+ _tracebackModule = nullptr ;
2638
2658
_ppsModule = nullptr ;
2639
2659
_Vector2TypeObject = nullptr ;
2640
2660
_Vector3TypeObject = nullptr ;
@@ -2711,7 +2731,7 @@ namespace py3lm {
2711
2731
2712
2732
PyObject* const pluginModule = PyImport_ImportModule (moduleName.c_str ());
2713
2733
if (!pluginModule) {
2714
- PyErr_Print ();
2734
+ LogError ();
2715
2735
return ErrorData{ std::format (" Failed to import {} module" , moduleName) };
2716
2736
}
2717
2737
@@ -2725,7 +2745,7 @@ namespace py3lm {
2725
2745
if (!pluginClass) {
2726
2746
Py_DECREF (classNameString);
2727
2747
Py_DECREF (pluginModule);
2728
- PyErr_Print ();
2748
+ LogError ();
2729
2749
return ErrorData{ " Failed to find plugin class" };
2730
2750
}
2731
2751
@@ -2734,7 +2754,7 @@ namespace py3lm {
2734
2754
Py_DECREF (pluginClass);
2735
2755
Py_DECREF (classNameString);
2736
2756
Py_DECREF (pluginModule);
2737
- PyErr_Print ();
2757
+ LogError ();
2738
2758
return ErrorData{ std::format (" Class '{}' not subclass of Plugin" , className) };
2739
2759
}
2740
2760
@@ -2743,7 +2763,7 @@ namespace py3lm {
2743
2763
if (!pluginInstance) {
2744
2764
Py_DECREF (classNameString);
2745
2765
Py_DECREF (pluginModule);
2746
- PyErr_Print ();
2766
+ LogError ();
2747
2767
return ErrorData{ " Failed to create plugin instance" };
2748
2768
}
2749
2769
@@ -2764,7 +2784,7 @@ namespace py3lm {
2764
2784
if (!pluginInfo) {
2765
2785
Py_DECREF (pluginInstance);
2766
2786
Py_DECREF (pluginModule);
2767
- PyErr_Print ();
2787
+ LogError ();
2768
2788
return ErrorData{ " Failed to save instance: plugin info not constructed" };
2769
2789
}
2770
2790
@@ -2773,7 +2793,7 @@ namespace py3lm {
2773
2793
if (resultCode != 0 ) {
2774
2794
Py_DECREF (pluginInstance);
2775
2795
Py_DECREF (pluginModule);
2776
- PyErr_Print ();
2796
+ LogError ();
2777
2797
return ErrorData{ " Failed to save instance: assignment fail" };
2778
2798
}
2779
2799
@@ -3396,15 +3416,15 @@ namespace py3lm {
3396
3416
3397
3417
PyObject* const nameString = PyUnicode_DecodeFSDefault (name.c_str ());
3398
3418
if (!nameString) {
3399
- PyErr_Print ();
3419
+ LogError ();
3400
3420
_provider->Log (std::format (" [py3lm] {}: failed to allocate name string" , context), Severity::Error);
3401
3421
return ;
3402
3422
}
3403
3423
3404
3424
if (PyObject_HasAttr (pluginData._instance , nameString)) {
3405
3425
PyObject* const returnObject = PyObject_CallMethodNoArgs (pluginData._instance , nameString);
3406
3426
if (!returnObject) {
3407
- PyErr_Print ();
3427
+ LogError ();
3408
3428
_provider->Log (std::format (" [py3lm] {}: call '{}' failed" , context, name), Severity::Error);
3409
3429
}
3410
3430
}
@@ -3414,7 +3434,50 @@ namespace py3lm {
3414
3434
return ;
3415
3435
}
3416
3436
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 {
3418
3481
_provider->Log (msg, Severity::Fatal);
3419
3482
}
3420
3483
0 commit comments