This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author Paul.Upchurch
Recipients Paul.Upchurch
Date 2011-09-06.18:41:49
SpamBayes Score 1.67542e-11
Marked as misclassified No
Message-id <1315334514.02.0.137561826697.issue12921@psf.upfronthosting.co.za>
In-reply-to
Content
Calling http.server.BaseHTTPRequestHandler.send_error(code,message) with a message that contains a trailing newline does not display properly in Firefox, Chrome.

Listing 1

#!/usr/bin/env python3.2

import http.server
import traceback

class httphandler(http.server.BaseHTTPRequestHandler):
  def do_GET(self):
    try:
      assert(False)
    except:
      self.send_error(500,traceback.format_exc())

if __name__=='__main__':
  addr=('',9000)
  http.server.HTTPServer(addr,httphandler).serve_forever()

Consider Listing 1. A typical programming idiom would be to wrap do_GET with a try/except block that reports an HTTP error with an HTML formatted stack trace. However, when I view this with Firefox and Chrome the error message is unformatted, i.e. raw HTML is displayed.

A simple workaround is to call strip() on the message. This could be suggested to the user in the docs, or added as an automatic preprocessing feature to the library. With strip(), the message is formatted.

Adding or documenting strip() resolves the bug. The remainder of this report is a feature request.

The default error_message_format is probably not what people want for a stack trace. It leaves formatting of whitespace to the HTML which removes the newlines. This is desirable for short, unformatted messages but undesirable for a preformatted traceback. In Listing 2 I give a working solution and suggest including it in the library if the community feels that preformatted messages are common enough to warrant extra attention. I feel it is since "try/except: print traceback" is almost mandatory for error prone internet operations.

Listing 2

#!/usr/bin/env python3.2

import http.server
import traceback

class httphandler(http.server.BaseHTTPRequestHandler):
  def content_aware_error_message_format(self,m):
    oldfmt='<p>Message: %(message)s.\n'
    if oldfmt in self.error_message_format:
      # use <pre> if the message contains a newline internally
      # otherwise let the html control line breaks
      self.error_message_format=self.error_message_format.replace(oldfmt,'<p><pre>%(message)s</pre>\n') if '\n' in m else self.error_message_format.replace(oldfmt,'<p>%(message)s\n')
  def do_GET(self):
    try:
      assert(False)
    except:
      m=traceback.format_exc().strip()
      self.content_aware_error_message_format(m)
      self.send_error(500,m)

if __name__=='__main__':
  addr=('',9000)
  http.server.HTTPServer(addr,httphandler).serve_forever()
History
Date User Action Args
2011-09-06 18:41:54Paul.Upchurchsetrecipients: + Paul.Upchurch
2011-09-06 18:41:54Paul.Upchurchsetmessageid: <1315334514.02.0.137561826697.issue12921@psf.upfronthosting.co.za>
2011-09-06 18:41:49Paul.Upchurchlinkissue12921 messages
2011-09-06 18:41:49Paul.Upchurchcreate