Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 1947

Show
Ignore:
Timestamp:
04/26/08 17:19:05
Author:
fumanchu
Message:

Applying Nicolas Griily's patch for #800.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/800-error-handlers/cherrypy/_cperror.py

    r1941 r1947  
    33from cgi import escape as _escape 
    44from sys import exc_info as _exc_info 
     5from traceback import format_exception as _format_exception 
    56from urlparse import urljoin as _urljoin 
    67from cherrypy.lib import http as _http 
     
    288289    if kwargs.get('version') is None: 
    289290        kwargs['version'] = cherrypy.__version__ 
     291     
    290292    for k, v in kwargs.iteritems(): 
    291293        if v is None: 
     
    294296            kwargs[k] = _escape(kwargs[k]) 
    295297     
    296     template = _HTTPErrorTemplate 
    297      
    298     # Replace the default template with a custom one? 
    299     error_page_file = cherrypy.request.error_page.get(code, '') 
    300     if error_page_file: 
     298    # Use a custom template or callable for the error page? 
     299    pages = cherrypy.request.error_page 
     300    error_page = pages.get(code) or pages.get('default') 
     301    if error_page: 
    301302        try: 
    302             template = file(error_page_file, 'rb').read() 
     303            if callable(error_page): 
     304                return error_page(**kwargs) 
     305            else: 
     306                return file(error_page, 'rb').read() % kwargs 
    303307        except: 
     308            e = _format_exception(*_exc_info())[-1] 
    304309            m = kwargs['message'] 
    305310            if m: 
    306311                m += "<br />" 
    307             m += ("In addition, the custom error page " 
    308                   "failed:\n<br />%s" % (_exc_info()[1])) 
     312            m += "In addition, the custom error page failed:\n<br />%s" % e 
    309313            kwargs['message'] = m 
    310314     
    311     return template % kwargs 
     315    return _HTTPErrorTemplate % kwargs 
    312316 
    313317 
     
    378382            [body]) 
    379383 
     384 
  • branches/800-error-handlers/cherrypy/_cprequest.py

    r1941 r1947  
    146146def error_page_namespace(k, v): 
    147147    """Attach error pages declared in config.""" 
    148     cherrypy.request.error_page[int(k)] = v 
     148    if k != 'default': 
     149        k = int(k) 
     150    cherrypy.request.error_page[k] = v 
    149151 
    150152 
     
    394396    error_page__doc = """ 
    395397    A dict of {error code: response filename or callable} pairs. 
    396     The named response files should be Python string-formatting templates, 
    397     and can expect by default to receive format values with the mapping 
    398     keys 'status', 'message', 'traceback', and 'version'. The set of 
    399     format mappings can be extended by overriding HTTPError.set_response. 
    400      
    401     If a callable is provided, it will be called with the HTTPError 
    402     instance as the only argument. The callable is expected to set 
    403     response.status, .headers and .body appropriately. 
    404      
    405     If no entry is given for an error code, the HTTPError's set_response 
    406     method will handle the error (by setting .status, .headers, and .body). 
     398     
     399    The error code must be an int representing a given HTTP error code, 
     400    or the string 'default', which will be used if no matching entry 
     401    is found for a given numeric code. 
     402     
     403    If a filename is provided, the file should contain a Python string- 
     404    formatting template, and can expect by default to receive format  
     405    values with the mapping keys %(status)s, %(message)s, %(traceback)s, 
     406    and %(version)s. The set of format mappings can be extended by 
     407    overriding HTTPError.set_response. 
     408     
     409    If a callable is provided, it will be called by default with keyword  
     410    arguments 'status', 'message', 'traceback', and 'version', as for a 
     411    string-formatting template. The callable must return a string which 
     412    will be set to response.body. It may also override headers or perform 
     413    any other processing. 
     414     
     415    If no entry is given for an error code, and no 'default' entry exists, 
     416    a default template will be used. 
    407417    """ 
    408418     
     
    600610                    cherrypy.response.finalize() 
    601611                except (cherrypy.HTTPRedirect, cherrypy.HTTPError), inst: 
    602                     ep = self.error_page.get(inst.status, '') 
    603                     if ep and callable(ep): 
    604                         ep(inst) 
    605                     else: 
    606                         inst.set_response() 
     612                    inst.set_response() 
    607613                    self.stage = 'before_finalize (HTTPError)' 
    608614                    self.hooks.run('before_finalize') 
     
    736742            cherrypy.response.finalize() 
    737743        except cherrypy.HTTPRedirect, inst: 
    738             ep = self.error_page.get(inst.status, '') 
    739             if ep and callable(ep): 
    740                 ep(inst) 
    741             else: 
    742                 inst.set_response() 
     744            inst.set_response() 
    743745            cherrypy.response.finalize() 
    744746 
     
    900902 
    901903 
     904 
  • branches/800-error-handlers/cherrypy/test/test_core.py

    r1941 r1947  
    242242     
    243243     
    244     def page401(e): 
    245         cherrypy.response.status = e.status 
    246         cherrypy._cperror.clean_headers(e.status) 
    247         cherrypy.response.body = "Well, I'm very sorry but you haven't paid!" 
     244    def callable_error_page(status, **kwargs): 
     245        return "Error %s - Well, I'm very sorry but you haven't paid!" % status 
    248246     
    249247     
     
    256254            raise cherrypy.HTTPError(int(err), "No, <b>really</b>, not found!") 
    257255        custom._cp_config = {'error_page.404': os.path.join(localDir, "static/index.html"), 
    258                              'error_page.401': page401
     256                             'error_page.401': callable_error_page
    259257                             } 
     258         
     259        def custom_default(self): 
     260            return 1 + 'a' # raise an unexpected error 
     261        custom_default._cp_config = {'error_page.default': callable_error_page} 
    260262         
    261263        def noexist(self): 
     
    729731            ignore.pop() 
    730732         
    731         # Test custom error page
     733        # Test custom error page for a specific error
    732734        self.getPage("/error/custom") 
    733735        self.assertStatus(404) 
    734736        self.assertBody("Hello, world\r\n" + (" " * 499)) 
    735737         
    736         # Test custom error page
     738        # Test custom error page for a specific error
    737739        self.getPage("/error/custom?err=401") 
    738740        self.assertStatus(401) 
    739         self.assertBody("Well, I'm very sorry but you haven't paid!") 
     741        self.assertBody("Error 401 Unauthorized - Well, I'm very sorry but you haven't paid!") 
     742         
     743        # Test default custom error page. 
     744        self.getPage("/error/custom_default") 
     745        self.assertStatus(500) 
     746        self.assertBody("Error 500 Internal Server Error - Well, I'm very sorry but you haven't paid!".ljust(513)) 
    740747         
    741748        # Test error in custom error page (ticket #305). 
     
    745752        msg = ("No, &lt;b&gt;really&lt;/b&gt;, not found!<br />" 
    746753               "In addition, the custom error page failed:\n<br />" 
    747                "[Errno 2] No such file or directory: 'nonexistent.html'") 
     754               "IOError: [Errno 2] No such file or directory: 'nonexistent.html'") 
    748755        self.assertInBody(msg) 
    749756         

Hosted by WebFaction

Log in as guest/cpguest to create tickets