J'utilise actuellement les éléments suivants pour générer une requête HTTP incorrecte:
raise tornado.web.HTTPError(400)
qui retourne une sortie HTML:
<html><title>400: Bad Request</title><body>400: Bad Request</body></html>
Est-il possible de ne renvoyer que le code de réponse HTTP avec un corps personnalisé?
Vous pouvez simuler 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>")
Tornado appelle RequestHandler.write_error
pour générer des erreurs. Une alternative à l’approche de VisioN serait donc la remplacer, comme suggéré par Tornado docs . L’avantage de cette approche est qu’elle vous permettra d’augmenter HTTPError
comme auparavant.
La source de RequestHandler.write_error
est ici . Vous trouverez ci-dessous un exemple de modification simple de write_error qui modifiera le code de statut et modifiera la sortie si vous fournissez une raison dans 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,
})
Il est préférable d'utiliser l'interface standard et de définir votre message personnalisé sur la variable HTTPError
.
raise tornado.web.HTTPError(status_code=code, log_message=custom_msg)
Vous pouvez ensuite analyser l'erreur dans votre RequestHandler
et rechercher le message suivant:
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>")
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))
quand jamais self.send_error () call est initié write_error () function est appelé par le gestionnaire de requêtes. Ainsi, vous pouvez créer votre dictée de données d'erreur personnalisée ici et la restituer à votre page d'erreur personnalisée.
http.responses [code_état] renvoie le texte du code d'erreur du type "page introuvable" en fonction du code d'état.
Vous pouvez aussi remplacer get_error_html method dans votre gestionnaire .
import tornado.web
class CustomHandler(tornado.web.RequestHandler):
def get_error_html(self, status_code, **kwargs);
self.write("<html><body><h1>404!</h1></body></html>")
...
def get(self):
...
Cet échange clarifie certaines des approches suggérées ici et actualise le mot clé reason
(que je pensais essayer).
Q: (par mrtn)
"Je souhaite utiliser raise tornado.web.HTTPError(400, reason='invalid request')
pour transmettre un motif personnalisé à la réponse d'erreur et j'espère pouvoir le faire en redéfinissant la méthode write_error (self, status_code, **kwargs)
.
"Mais il semble que je ne peux accéder qu'à self._reason
à l'intérieur de write_error
, ce qui n'est pas ce que je veux. J'ai aussi essayé kwargs['reason']
mais cela n'existe pas."
A: (par le développeur principal de Tornado @bendarnell)
"L'exception qui a exposé l'erreur est disponible pour write_error
sous la forme d'un triple exc_info
dans les arguments de mots clés. Vous pouvez accéder au champ de motif avec quelque chose comme:
if "exc_info" in kwargs:
e = kwargs["exc_info"][1]
if isinstance(e, tornado.web.HTTPError):
reason = e.reason
"Mais notez que le champ reason
est essentiellement obsolète (il n’est pas présent dans HTTP/2), ce n’est donc probablement pas la meilleure façon de faire ce que vous essayez de faire ici (le champ HTTPError
de log_message
est un peu mieux, mais toujours pas Créez simplement votre propre exception au lieu d’utiliser HTTPError
; votre substitution write_error
peut utiliser self.set_status(400)
lorsqu’elle détecte le type d’exception approprié. "