Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I return HTTP error code without default template in Tornado?

Tags:

python

tornado

I am currently using the following to raise a HTTP bad request:

raise tornado.web.HTTPError(400)

which returns a html output:

<html><title>400: Bad Request</title><body>400: Bad Request</body></html>

Is it possible to return just the HTTP response code with a custom body?

like image 756
S-K' Avatar asked Dec 05 '12 19:12

S-K'


People also ask

What is Tornado template?

A Tornado template is just HTML (or any other text-based format) with Python control sequences and expressions embedded within the markup: <html> <head> <title>{{ title }}</title> </head> <body> <ul> {% for item in items %} <li>{{ escape(item) }}</li> {% end %} </ul> </body> </html>

How many requests can Tornado handle?

Python Tornado Request Performance.md Meaning tornado will be able to handle a maximum of 10 simultaneous fetch() operations in parallel on each IOLoop. This means a single tornado process should only be able to handle ~3 incoming requests before subsequent ones would queue in Tornado's AsyncHTTPClient.

What is Tornado web application?

A Tornado web application generally consists of one or more RequestHandler subclasses, an Application object which routes incoming requests to handlers, and a main() function to start the server. A minimal “hello world” example looks something like this: import asyncio import tornado.web class MainHandler(tornado.


4 Answers

You may simulate RequestHandler.send_error method:

class MyHandler(tornado.web.RequestHandler):
    def get(self):
        self.clear()
        self.set_status(400)
        self.finish("<html><body>My custom body</body></html>")
like image 108
VisioN Avatar answered Nov 08 '22 02:11

VisioN


Tornado calls RequestHandler.write_error to output errors, so an alternative to VisioN's approach would be override it as suggested by the Tornado docs. The advantage to this approach is that it will allow you to raise HTTPError as before.

The source for RequestHandler.write_error is here. Below you can see an example of a simple modification of write_error that will change the set the status code and change the output if you provide a reason in kwargs.

def write_error(self, status_code, **kwargs):
    if self.settings.get("serve_traceback") and "exc_info" in kwargs:
        # in debug mode, try to send a traceback
        self.set_header('Content-Type', 'text/plain')
        for line in traceback.format_exception(*kwargs["exc_info"]):
            self.write(line)
        self.finish()
    else:
        self.set_status(status_code)
        if kwargs['reason']:
            self.finish(kwargs['reason'])
        else: 
            self.finish("<html><title>%(code)d: %(message)s</title>"
                "<body>%(code)d: %(message)s</body></html>" % {
                    "code": status_code,
                    "message": self._reason,
                })
like image 26
Rod Hyde Avatar answered Nov 08 '22 01:11

Rod Hyde


It's better to use the standard interface and define your custom message on the HTTPError.

raise tornado.web.HTTPError(status_code=code, log_message=custom_msg)

You can then parse the error in your RequestHandler and check for the message:

class CustomHandler(tornado.web.RequestHandler):
    def write_error(self, status_code, **kwargs):
        err_cls, err, traceback = kwargs['exc_info']
        if err.log_message and err.log_message.startswith(custom_msg):
            self.write("<html><body><h1>Here be dragons</h1></body></html>")
like image 6
punkrockpolly Avatar answered Nov 08 '22 03:11

punkrockpolly


def write_error(self, status_code, **kwargs):
    #Function to display custom error page defined in the handler.
    #Over written from base handler.
    data = {}
    data['code'] = status_code
    data['message'] = httplib.responses[status_code]
    # your other conditions here to create data dict
    self.write(TEMPLATES.load('error.html').generate(data=data))

when ever self.send_error() call is initiated write_error() function is called by the request handler. So you can create your custom error data dict here and render it to your custom error page.

http.responses[status_code] returns the error code text like "page not found" based on the status code.

like image 5
Somesh Avatar answered Nov 08 '22 02:11

Somesh