Useful traceback eaten up by flame?

Hi Franck @lambertz,
Good idea for where errors are kind of expected, like when something might return none or other situations, I guess. Especially when the script is finished but errors might still happen? Thanks. Hope you’re well!

Thanks @Ryland, I’ll try feeding the pyi and see how much it helps. I wasn’t thinking of chatGPT to find errors btw, more like highjacking my own question/thread. uploading to chatGPT every time there’s an error when building a script might be a bit tedious. I’ve tried it to create test scripts (No flame involved) with a UI (PySide6) and data manipulation/display. It worked and I could then wrap my head around ideas quickly.

Thanks Kieran @knhn. Yeah, I sometime end up adding print(test01), 2, 3, 4 …
To see where it breaks.

A standard traceback with line numbers would be sooo much simpler!

Hey Stephan!

I heard my name so I popped out of the bottle.

Man, I haven’t updated flame.pyi in a while. I used Pycharm + CoPilot for flame scripts and I have Flame open and use the “Refresh Python Hooks” to reload the code. From what i recall it only reloads the hook functions and (maybe) the file they live in and NOT auxiliary .py files you imported. I think that’s why I actually put a lot of my imports INSIDE the functions just in case.

Flame scripters tend to make “monolithic/one file” scripts, probably because of this behavior.

Anyways, because CoPilot can use the context of your project files, I haven’t had much need to update the flame.pyi for autocompletion and I think the old flame.pyi covers 90% of what you need. But I’ll make a separate post about this and share my .pyi generator.

Re: traceback

I didn’t know about “DL_DEBUG_PYTHON_HOOKS”! Nice tip!

Flame debugging is pretty painful so I implemented 2 things to make it easier:

  1. Custom loggers for stdout/stderr output with color coding. I basically have 2 macros “DBUG” and “WARN” that implement Python’s Logger lib. The logger has awesome format options to print the function name, time, line number, etc.

  2. I made a “CatchAll” decorator that you can sprinkle on your hooks that basically wraps that function in a try/catch. It will catch any uncaught exceptions and create a QT dialog and also log/slack the error. It uses Python’s “traceback” library to give you proper error output with file names and line numbers:

I’ve attached mw_debug.py. You can import the DBUG and WARN macros like this:

from mw_debug import *

def foo(blah):
   DBUG("Just saying hi")
   for x in y:
      DBUG(f"x = {x}")
   WARN("Something bad happened")

mw_debug.py (2.5 KB)

Here’s the catchall decorator. You use it like this:

from mw_catchall import *

@catchall
def my_flame_hook(selection):
   ...

mw_catchall.py (941 Bytes)

OMG, I just read my comments of the decorator…haha:

This is an annotation function meant to be used to help debug functions and catch exceptions.
USAGE: @catchall   (add this on the line before the function you want to debug.)
The exceptions thrown by Flame don't have the line numbers or function names so this prints
out the missing info.

OR…

Now that I’m looking at the catchall code…you can achieve what you want to do by using the traceback function. So you can wrap a section in try/catch and in the catch all you need to do is call “traceback.format_exc()”. I would start with this first!!!

        import traceback
        try:
            foo(blah)
        except Exception as e:
            errormsg = '\n' + traceback.format_exc()
            print(errormsg)

Disclaimer: This code is provided as is and I and my company “Mr. Wolf” take no responsibility for any harm or issues you have. You are free to use for internal company or personal use. Don’t use it in a commercial product.

Hit me up if you have any questions!
-Danny

5 Likes

Hey Danny!

Thanks so much for this very detailed, super useful info and material, appreciated.
Haha, yeah that comment is basically a direct answer to the main question :slight_smile:
This last bit using traceback seems on par with @lambertz solution, minus the external log file part.

For updating auxiliary imported files/modules as well when rescanning the hooks, I use a temporary reload

from importlib import reload
import some_module
reload(some_module)

I turn it off when done debugging or ‘building’

Stefan

2 Likes

@DannyYoon - legend.

1 Like

@fredwarren, anyway Flame could simply not ‘hide’ the traceback please?
Seems a bit silly that many talented people making tools for Flame have to use all these workarounds …

Just wanted to add that trying to redirect uncaught exceptions by overriding the main sys.excepthook doesn’t work. It seems Flame is intercepting the exception stack.

2 Likes

Thanks for chiming in and welcome to the logik forum, @Tommy :clap:

1 Like

Funny how all the heavy contributors work at the same shop
:rofl:

Again nice tip! I’ll definite use it!

1 Like

Hey Phil! What better way to get together with friends than over some Python shenanigans…

fuck python brother - where’s the money?