error.py
changeset 135 19ff083c2870
parent 134 fbccc1648d79
child 136 c69a176b3620
equal deleted inserted replaced
134:fbccc1648d79 135:19ff083c2870
     1 """
     1 """
     2     Build error messages
     2     Build error messages
     3 """
     3 """
     4 
     4 
     5 import traceback, sys
     5 import traceback, sys, cgi, urllib
     6 
     6 
     7 def build_error (exc_info=None) :
     7 def build_error (exc_info=None, env=None) :
     8     """
     8     """
     9         Dumps out a raw traceback of the given/current exception to stdout.
     9         Dumps out a raw traceback of the given/current exception to stdout.
       
    10 
       
    11         If request_env, it should be a environment dict, like under WSGI, and will be used to display additional info
       
    12         about the request.
    10 
    13 
    11         Returns a (status, content-type, body) tuple, with all components being non-unicode strs.
    14         Returns a (status, content-type, body) tuple, with all components being non-unicode strs.
    12     """
    15     """
    13 
    16 
    14 
    17     # default for exc_info is current exception
    15     # default
       
    16     if not exc_info :
    18     if not exc_info :
    17         exc_info = sys.exc_info()
    19         exc_info = sys.exc_info()
       
    20 
       
    21     # request URL?
       
    22     if env :
       
    23         try :
       
    24             from qmsk.web.http import request_url
       
    25 
       
    26             url = request_url(env)
       
    27 
       
    28         except :
       
    29             # ignore
       
    30             url = None
       
    31     else :
       
    32         url = None
       
    33 
       
    34     # working copy path?
       
    35     try :
       
    36         from config import HG_WC_PATH
       
    37 
       
    38         wc_path = HG_WC_PATH
       
    39 
       
    40     except :
       
    41         # a good guess
       
    42         wc_path = '.'
       
    43     
       
    44     # version?
       
    45     try :
       
    46         from version import version_string
       
    47 
       
    48         version = version_string(wc_path)
       
    49     
       
    50     except :
       
    51         version = None
       
    52     
       
    53     # the exception type
       
    54     exception_str = traceback.format_exception_only(*exc_info[:2])[-1][:255]
       
    55 
       
    56     # the exception traceback
       
    57     traceback_lines = traceback.format_exception(*exc_info)
       
    58 
       
    59     # XXX: make this configureable
       
    60     trac_url = "http://projects.qmsk.net/irclogs2/trac"
       
    61     
       
    62     # ticket list
       
    63     query_url = "%s/query" % trac_url
       
    64 
       
    65     # submit ticket
       
    66     submit_args = dict(type='defect')
       
    67 
       
    68     if url :
       
    69         submit_args['url'] = url
       
    70 
       
    71     if version :
       
    72         submit_args['revision'] = version
       
    73     
       
    74     if exception_str :
       
    75         submit_args['summary'] = exception_str
       
    76 
       
    77     if traceback_lines :
       
    78         # this is big
       
    79         submit_args['description'] = """\
       
    80 [Insert any additional information here]
       
    81 
       
    82 
       
    83 = Traceback =
       
    84 {{{
       
    85 %s
       
    86 }}}""" % ''.join(traceback_lines)
       
    87     
       
    88     # the trac newticket URL
       
    89     submit_url = "%s/newticket?%s" % (trac_url, '&'.join('%s=%s' % (urllib.quote(k), urllib.quote(v)) for k, v in submit_args.iteritems()))
    18 
    90 
    19     # return
    91     # return
    20     return ('500 Internal Server Error', 'text/html; charset=UTF-8', ("""\
    92     return ('500 Internal Server Error', 'text/html; charset=UTF-8', ("""\
    21 <html><head><title>500 Internal Server Error</title></head><body>
    93 <html><head><title>500 Internal Server Error</title></head><body>
    22 <h1>Oops!</h1>
    94 <h1>Oops!</h1>
    23 <p>
    95 <p>
    24     An error occured, which was not logged, and will not be reported to anybody. It might be your fault, or it might be
    96     An error occured, which was not logged, and will not be reported to anybody. It might be your fault, or it might be
    25     the programmer's, but it's probably not mine. If you think you really care, you can try poking the administrator of
    97     mine. 
    26     this site to see if they respond. 
       
    27 </p>
    98 </p>
    28 <p>
    99 <p>
    29     If you do so, please include the following information:
   100     You can try poking the administrator of this site to see if they respond, or submit a defect ticket at the <a href="%(query_url)s">Project Trac</a>, using the following link:
    30 </p>
   101 </p>
       
   102 <pre>
       
   103     <a href="%(submit_url)s">%(submit_url_short)s</a>
       
   104 </pre>
    31 <h2>Details:</h2>
   105 <h2>Details:</h2>
    32 <pre>%(traceback)s</pre>
   106 <pre>%(traceback)s</pre>
    33 </body></html>""" % dict(
   107 </body></html>""" % dict(
    34         traceback   = ''.join(traceback.format_exception(*exc_info))
   108         traceback           = cgi.escape(''.join(traceback_lines)),
       
   109         query_url           = query_url,
       
   110         submit_url          = submit_url,
       
   111         submit_url_short    = submit_url[:120] + '...'
    35     )).encode('utf-8'))
   112     )).encode('utf-8'))
    36 
   113