přihlásit 4720/824557

Ladící výpis výjimky

Tohle je poměrně užitečná ukázka vylepšeného chybového hlášení k zachycené výjimce. Lze vypsa na obrazovku, uložit do logu nebo databáze, ze serveru poslat klientovi a podobně. Uživatel to asi příliš neocení, ale pro programátora je to výborná pomůcka při ladění programu.

Najzajímavější na tom bude asi:

Ke stažení

demefrex.py - 3 182 B (debug message from exception)

Ukázky

standardní chybový výpis

Traceback (most recent call last):
  File "u_trace.py", line 119, in ?
    first()
  File "u_trace.py", line 101, in first
    first_in(1, 0)
  File "u_trace.py", line 97, in first_in
    d = a/b
ZeroDivisionError: integer division or modulo by zero

vylepšený chybový výpis

======================================================================
EXCEPTION: exceptions.ZeroDivisionError
ERROR MSG: integer division or modulo by zero
TRACE: 
   u_trace.py/109 main: first()
   u_trace.py/101 first: first_in(1, 0)
   u_trace.py/97 first_in: d = a/b
CODE: 
   93     def first_in(a, b):
   94         ''' Testovaci funkce kde dojde k vyjimce. '''
   95 
   96         c = ['q', 123, None]
   97         d = a/b
LOCAL VARS:
   a = (<type 'int'>) 1
   b = (<type 'int'>) 0
   c = (<type 'list'>) ['q', 123, None]
----------------------------------------------------------------------

Kód programu demefrex.py

# encoding: utf-8
import sys, inspect, pprint

MAX_STRLEN_VALUE = 60
MIN_CODE_LINES = 10

def getTextFromCode(code, offset, linenu):
    ''' Print relevant part source code. '''
    code = code[:offset+1]
    code.reverse()

    shortCode = []
    for i, line in enumerate(code):
        sLine = line.strip()
        if  sLine[:3] == 'def':
            shortCode.insert(0, line)
            break
        if  sLine[:5] == 'class':
            shortCode.insert(0, line)
            break
        if  sLine == '' and i > MIN_CODE_LINES:
            break
        shortCode.insert(0, line)

    offset = len(shortCode)-1
    TEXT = []
    for i, line in enumerate(shortCode):
        number = linenu-offset+i
        line   = line[:-1]
        TEXT.append("%5d %s" % (number, line))
    return '\n'.join(TEXT)

def getTextFromDict(d, title=None):
    ''' Pretty print of dict. '''
    TEXT = []
    if  title:
        TEXT.append(title)
    keys = d.keys()
    keys.sort()

    keyMaxLen = 0
    for key in keys:
        if  len(key) > keyMaxLen:
            keyMaxLen = len(key)

    keyMaxLen += 3
    pattern = '%%%ds = (%%s) %%s' % keyMaxLen
    for key in keys:
        TEXT.append(pattern % (key, type(d[key]), str(d[key])[:MAX_STRLEN_VALUE]))
    return '\n'.join(TEXT)

def makeTextFromException(size='full'):
    ''' Make information about exception. '''
    TEXT = []

    typerr,strerr,c = sys.exc_info()
    TEXT.append('\n==================================================================')
    TEXT.append('EXCEPTION: ' + str(typerr))
    TEXT.append('TRACE: ')
    traceback = inspect.trace(100)

    last = len(traceback) - 1
    for i, (frame, file, linenu, object, code, offset) in enumerate(traceback):
        if  code and code[offset]:
            example = code[offset].strip()
        else:
            example = '<N/A>'

        if  size == 'full' or i == last:
            TEXT.append('   %s/%d %s: %s' % (file, linenu, object, example))

        if(i == last):
            if  code and size == 'full':
                TEXT.append('CODE: ')
                TEXT.append(getTextFromCode(code, offset, linenu))
            TEXT.insert(2, 'ERROR MSG: ' + str(strerr))
            if  size == 'full':
                TEXT.append(getTextFromDict(frame.f_locals, 'LOCAL VARS:'))

    TEXT.append('------------------------------------------------------------------')
    return '\n'.join(TEXT)

## SELF TEST ##############################################

if  __name__ == "__main__":

    class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return str(self.value)

    def first_in(a, b):
        ''' Testovaci funkce kde dojde k vyjimce. '''

        c = ['q', 123, None]
        d = a/b

    def first():
        ''' Testovaci funkce. '''
        first_in(1, 0)

    def second():
        raise MyError("můj error")

    def main():
        ''' Self test. '''
        try:
            first()
        except:
            print makeTextFromException()

        try:
            second()
        except:
            print makeTextFromException()

    main()

Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in /web/htdocs2/wraithcz/home/www/python/data/sessions/sessions1.php on line 2