Making Python Scripts Show Windows-friendly Errors/Stacktrace

2007 June 20
by Arun Bhai

Most of us love to distribute our python programs to others once you have finished coding a neat little script. For Windows users we package it using Py2exe or cx_freeze. However, many of the end-users will not be happy with a black command window popping up, say, when an error is thrown.

Of course the alternative is to write a full blown GUI application using WXPython or PyFLTK. Even the latter, though quite lightweight, adds several megabytes to the distribution, when all you need is a simple message-box indicating an error or showing some informational text. Clearly, its an overkill for your throwaway python scripts.

This is the kind of problem I typically face and I have found a good solution. The answer is ctypes library which comes as a part of the standard distribution from Python 2.5 onwards. It simply calls the messagebox function from user32.dll (which is always present in a windows installation). With the main problem solved, what remained was to obtain the error text and stack trace.

Let’s see how the code looks like:

# Importing all the works for a native Win32 Message Box
from ctypes import c_int, WINFUNCTYPE, windll
from ctypes.wintypes import HWND, LPCSTR, UINT
prototype = WINFUNCTYPE(c_int, HWND, LPCSTR, LPCSTR, UINT)
paramflags = (1, "hwnd", 0), (1, "text", "Hi"), (1, "caption", None), (1, "flags", 0)
MessageBox = prototype(("MessageBoxA", windll.user32), paramflags)

# For printing the stack
import sys
import traceback
from time import sleep

def show_popup(text):
    print text
    MessageBox(text=text, caption="Sample App Says...")

def mainloop():
    raise "Uff!"

if __name__ == '__main__':
    try:
        mainloop()
    except:
        type, value, sys.last_traceback = sys.exc_info()
        lines = traceback.format_exception(type, value,sys.last_traceback)
        show_popup("Aiyooooo..... there has been an error!\n" +
            "Exception in user code:\n" +
            "".join(lines) +
            "===== Please mail a screenshot to arunvr@gmail.com ===="
            )
    finally:
        sleep(1) # show the console output for a second so that users can read it

EDIT: This is how it looks like in PyMail, one of my scripts-that-grew-into-an-app ;)

Screenshot of a Python Stacktrace in a Messagebox

Distantly Related posts:

  1. Work Faster in Windows With Launchy and a few Python Scripts
  2. Windows+Python Integration Like Unix shell
  3. Workaround to Easy Install PIL on Windows
  4. Is Python Intellisense Possible in Emacs?
  5. Indie Film Making against Odds
No comments yet

Leave a Reply

Note: You can use basic XHTML in your comments. Your email address will never be published.

Subscribe to this comment feed via RSS

Additional comments powered by BackType