How to save Errors to a Text File?

I would like to publish an “early” version of my game, and i want to make it so when there is any error somewhere in a script, it displays a message to the screen AND adds itself to a text file.

So i can debug the bugs that occur on someone else’s PC (so the others can send me the text file)

How can i do that?

edit:
i know i could just make try: except: everywhere but i think thats inefficient + bad code

try command prompt option debug


blender.exe -debug > file

maybe -debug-all

how do i do that? i normally dont use the command prompt

You can just ctrl + print screen the errors and dump the paste into a paint file.

@Leralasss
Windows, open the folder that has blender.exe in it by using windows explorer
press alt+d, ctrl+c, that copies the location of blender.exe
press start menu button, widows logo on the lower left that shows you your apps if you have windows 7
right above the start button in windows 7 is a field input box, type cmd.exe, hit enter
right click the black area of the widow and paste the location
append the command \blender.exe -debug-all > file to the end of the location
and hit enter
windows 10 is same except you have to find cmd.exe in C:<b>Windows\System32 and click on cmd.exe to start command prompt

alt+PrtScn will only capture the active window

@ed from america

is there another way? that way only works when you do those steps before right? (or does it work for everyone else too if i do that?)
but i want to make an easy way for others to just send me a file or something

before you get started using command line instructions on a bigger scale test the debug option on blender to see if it reports errors

sys.excepthook is a python function that runs whenever a script throws an exception.

Here is an example (not fully tested):


import sys

def _exception_handler(type_, value, traceb):
    '''Runs whenever there is a python exception'''
    error_message = ''.join(traceback.format_exception(type_, value, traceb))
    print(error_message)
    with open('log.txt', 'a') as out_file:
    out_file.write(error_message)
    out_file.write('
')

sys.excepthook = _exception_handler

I generally combine this with a logging module so instead of using “print” you use a custom “log” function. If you use the traceback module inside the “log” function, you can get the entire call stack printed for each log statement (so you can see what ran it). Snippets from a log on one of my systems:

/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/game/__init__.py:8
&lt;Snipping log for obfuscation&gt;
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/common/__init__.py:59
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/common/__init__.py:30
INFO: Root Path: /mnt/Data/Work/&lt;obfuscated&gt;


/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/game/__init__.py:8
&lt;Snipping log for obfuscation&gt;
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/widgets/__init__.py:3
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/widgets/button.py:3
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/language/__init__.py:44
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/language/__init__.py:42
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/language/language_file.py:24
INFO: Loading Language: english


/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/game/__init__.py:16
&lt;Snipping log for obfuscation&gt;
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/loader/libload.py:34
INFO: Loading Blend: /mnt/Data/Work/&lt;obfuscated&gt;/Data/Models/arm.blend


/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/game/__init__.py:23
&lt;Snipping log for obfuscation&gt;
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/widgets/button.py:37
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/widgets/button.py:33
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/sounds/soundtypes.py:13
/home/geoffrey/Work/&lt;obfuscated&gt;/Data/Scripts/sounds/cache.py:20
INFO: Loading sound: /mnt/Data/Work/&lt;obfuscated&gt;/menu_select.wav


/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/common/__init__.py:40
ERROR: Traceback (most recent call last):
  File "/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/menus/mainmenu.py", line 11, in &lt;module&gt;
    import game
&lt;Snipping log for obfuscation&gt;
  File "/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/robot/manipulator.py", line 23, in &lt;module&gt;
    import loader
  File "/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/loader/__init__.py", line 5, in &lt;module&gt;
    from .libload import LoadBlend, lib_load_unique, LoadAddObject
  File "/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/loader/libload.py", line 15, in &lt;module&gt;
    class LoadBlend(object):
  File "/mnt/Data/Work/&lt;obfuscated&gt;/Data/Scripts/loader/libload.py", line 23, in LoadBlend
    some_random_error
NameError: name 'some_random_error' is not defined

Obfuscated as some of the material is slightly sensitive at this point in time.
Yes, I have had to use these logs to solve issues that arise on remote systems and they are very useful.

Nice, thanks, i’ll try that out!

edit:
it works!


If you were a really pro developer, you’d add some code to email yourself the error message too.
Not really, that would be a nightmare.

Things like this can really improve your development process massively. It’s also why using a powerful IDE can make you more productive - good tooling makes programming more painless.

@agoose:
I have considered adding an “email the developer” button onto some bits of internal-only software…

I would reword your post to say that using “a powerful set of tools can make you more productive” - I often find that a “powerful” IDE is not the optimal solution. When I type into a script file, I want the fastest route to convert from code in my head into code in the computer. As a result, I detest autocompletes, on-the-fly syntax checking and so on. I find they distract me, and make me lose my train of thought.
However, I do have a makefile setup to do code quality analysis, unit testing and so on, but they happen after the code is already written down and is about to be executed.

But on the whole I agree. Good tooling does make programming more painless.

Given that the OP has marked solved we’re probably good to discuss here.

Indeed, I followed “things like this can …” with IDEs to implicitly refer to tooling. I’ve used a range of IDEs like VSCode, VS, atom, PyCharm, Eclipse, Aptana, Netbeans (even Notepad++ if you consider it an IDE), and found that inspection & autocomplete tools are only really useful if they’re actually intelligent. With Py3.5/6 support for typing, and a half-decent inspection backend, it actually can be useful. I rarely use the autocomplete, but most benefit from the type checking tools. My preferred IDE, PyCharm, is leagues ahead, though, providing PEP8 compliant refactoring, context-aware renaming of methods/attributes/variables, and other features which I find allows me to focus more on what I’m writing, rather than the necessary evils of writing code itself.

Regarding tooling, I am particular interested in integrating MyPy into my next project.

Hmm… So we pipe the error messages to a in game text system :smiley: