0

I have following Application configuration:

settings = {
    'default_handler_class': BaseHandler
}

app = web.Application([
        (r'/', IndexHandler),
        (r'/ws', SocketHandler),
        (r'/js/(.*)', web.StaticFileHandler, {'path': 'assets/js', 'default_filename': 'templates/error.html'}),
        (r'/css/(.*)', web.StaticFileHandler, {'path': 'assets/css'}),
        (r'/images/(.*)', web.StaticFileHandler, {'path': 'assets/images'})
    ], **settings)

When I type in http://localhost:8888/js/d3.min.js the file is served, but when I mispell file name and provide http://localhost:8888/js/d3.mi.js for example I would like to obtain my default error page which is located at templates/error.html. For URL like http://localhost:8888/not/existing it works fine but the http://localhost:8888/js/d3.mi.js gives me just plain 404: Not Found.

I found following part in documentation:

To serve a file like index.html automatically when a directory is requested, set static_handler_args=dict(default_filename="index.html") in your application settings, or add default_filename as an initializer argument for your StaticFileHandler.

However I can't understand where I should specify mentioned code. The 'default_filename': 'templates/error.html' in my code doesn't work.

Julian Rubin
  • 1,175
  • 1
  • 11
  • 23
  • 1
    I found this post http://stackoverflow.com/questions/26011924/tornado-custom-error-handler-for-static-file. It's a fairly old post, so I'm not sure if things have changed in the recent version of Tornado. This question has me really thinking about my own code dealing with static files. – notorious.no Mar 21 '16 at 00:42

2 Answers2

1

In fact The 'default_filename' work well in your code.

What does default_filename mean ?

"default_filename" means that if you request a directory such as "http://localhost:1234/js/" ,server will return a default file to you. so, you must be aware that "default file" is not error file, "default_filename" isn't what you need.

What do you need?

to write a subclass of "StaticFileHandler" will resolve. in the method "validate_absolute_path" of "StaticFileHandler"

   if not os.path.exists(absolute_path):
        raise HTTPError(404)

Don't raise 404, just return your error file path (such as js/error.js). Good luck!

my english is poor, i don't known if you can get it ^_^. it's my pleasure to exchange experience with you.

1

default_filename

The file specified in default_filename should be in given static path. So if you move error.html to assets/js directory, than navigate to /js/ you will see content of error.html.

Basically this functionality is a helper with limited usecase (imho). More at https://stackoverflow.com/a/27891339/681044.

Custom error pages

Every request handler handles/renders errors in write_error function. This is the recommended way to create custom error pages:

class MyStaticFileHandler(tornado.web.StaticFileHandler):

    def write_error(self, status_code, *args, **kwargs):
        # custom 404 page
        if status_code in [404]:
            self.render('templates/error.html')
        else:
            super().write_error(status_code, *args, **kwargs)
Community
  • 1
  • 1
kwarunek
  • 12,141
  • 4
  • 43
  • 48