web-dev-qa-db-fra.com

Google App Engine et erreur 404

J'ai configuré un site Web statique sur GAE à l'aide d'indices trouvés ailleurs, mais je ne vois pas comment renvoyer une erreur 404. Mon fichier app.yaml ressemble à

- url: (.*)/
  static_files: static\1/index.html
  upload: static/index.html

- url: /
  static_dir: static

avec tous les fichiers html/jpg statiques stockés dans le répertoire static. Ce qui précède fonctionne pour les fichiers existants, mais retourne un fichier de longueur NULL s'ils ne le font pas. La réponse est probablement d'écrire un script python pour renvoyer une erreur 404, mais comment configurer les choses pour servir les fichiers statiques existants tout en exécutant le script pour les fichiers qui n'en ont pas?

Voici le journal de récupération d'un fichier non existant (nosuch.html) sur le serveur d'applications de développement:

ERROR    2008-11-25 20:08:34,084 dev_appserver.py] Error encountered reading file "/usr/home/ctuffli/www/tufflinet/static/nosuch.html":
[Errno 2] No such file or directory: '/usr/home/ctuffli/www/tufflinet/static/nosuch.html'
INFO     2008-11-25 20:08:34,088 dev_appserver.py] "GET /nosuch.html HTTP/1.1" 404 -
37
ctuffli

Vous devez enregistrer un gestionnaire de script fourre-tout. Ajoutez ceci à la fin de votre app.yaml:

- url: /.*
  script: main.py

Dans main.py, vous devrez mettre ce code:

from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

class NotFoundPageHandler(webapp.RequestHandler):
    def get(self):
        self.error(404)
        self.response.out.write('<Your 404 error html page>')

application = webapp.WSGIApplication([('/.*', NotFoundPageHandler)],
                                     debug=True)

def main():
    run_wsgi_app(application)

if __== "__main__":
    main()

Remplacez <Your 404 error html page> par quelque chose de significatif. Ou mieux utilisez un modèle, vous pouvez lire comment faire cela ici .

S'il vous plaît laissez-moi savoir si vous avez des problèmes pour le mettre en place.

37

google App Engine a maintenant Réponses d'erreur personnalisées

afin que vous puissiez maintenant ajouter une section error_handlers à votre app.yaml, comme dans cet exemple:

error_handlers:

- file: default_error.html

- error_code: over_quota
    file: over_quota.html
27
jonmiddleton

Une façon beaucoup plus simple de faire cela sans nécessiter de cycle de processeur consiste à placer ce gestionnaire au bas de votre application.yaml

- url: /.*
    static_files: views/404.html
    upload: views/404.html

Cela vous permet ensuite de placer un fichier statique 404.html dans votre répertoire de vues. Pas besoin d'un gestionnaire de python. Tout ce qui n'est pas déjà traité dans votre application.yaml le fera déjà.

5
Zee Spencer

Vous pouvez créer une fonction pour gérer vos erreurs pour n’importe quel code d’état. Vous êtes en train d'être 404, définissez une fonction comme ceci: 

def Handle404(request, response, exception):
     response.out.write("Your error message") 
     response.set_status(404)`

Vous pouvez transmettre n'importe quoi - HTML/texte brut/modèles dans la fonction response.out.write. Maintenant, ajoutez la déclaration suivante après votre déclaration app.

app.error_handlers[404] = Handle404

Cela a fonctionné pour moi.

4
theG33k

webapp2 fournit le dictionnaire error_handlers que vous pouvez utiliser pour afficher des pages d'erreur personnalisées. Exemple ci-dessous:

def handle_404(request, response, exception):
    logging.warn(str(exception))
    response.set_status(404)
    h = YourAppBaseHandler(request, response)
    h.render_template('notfound')

def handle_500(request, response, exception):
    logging.error(str(exception))
    response.set_status(500)
    h = YourAppBaseHandler(request, response)
    h.render_template('servererror')

app = webapp2.WSGIApplication([
    webapp2.Route('/', MainHandler, name='home')
    ], debug=True)
app.error_handlers[404] = handle_404
app.error_handlers[500] = handle_500

Plus de détails sont disponibles sur les pages de documentation de webapp2: http://webapp-improved.appspot.com/guide/app.html#error-handlers

3
Romain

J'ai examiné toutes les réponses données ci-dessus et utilisé les éléments suivants à la fin comme solution 404 la plus universelle:

Ajouter ce lien à la fin de app.yaml

- url: /(.*) 
  script: 404.app

et créez 404.py avec le contenu suivant

import webapp2
from google.appengine.ext.webapp import template

class NotFound(webapp2.RequestHandler):
  def get(self):
    self.error(404)
    self.response.out.write(template.render('404.html', {}))

app = webapp2.WSGIApplication([
    ('/.*', NotFound)
], debug=True)

Cela affichera le contenu du fichier 404.html avec le code d'erreur 404.

L'avantage de cette solution est la simplicité, l'exactitude du comportement et la flexibilité, car elle permet d'utiliser un fichier 404.html statique comme contenu de page d'erreur.

Je tiens également à mettre en garde contre certaines des solutions suggérées ci-dessus. 

  • Custom Error Responses ne fonctionne pas avec l'erreur 404
  • N'utilisez pas non plus de fichiers statiques, car ils renverraient une erreur 200 au lieu d'une erreur 404. Cela peut causer beaucoup de maux de tête à venir.
2
husayt

Le serveur dev_appserver renvoie déjà 404 réponses pour tout ce qui ne correspond pas au mappage, ou correspond au mappage mais n'existe pas. La réponse 404 elle-même n'a pas de corps, mais reste une 404:

$ wget -O - http://127.0.0.1:8080/foo
--2010-10-28 10:54:51--  http://127.0.0.1:8080/foo
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 404 
2010-10-28 10:54:51 ERROR 404: (no description).

$ wget -O - http://127.0.0.1:8080/foo/
--2010-10-28 10:54:54--  http://127.0.0.1:8080/foo/
Connecting to 127.0.0.1:8080... connected.
HTTP request sent, awaiting response... 404 
2010-10-28 10:54:54 ERROR 404: (no description).

Si vous souhaitez retourner une page d'erreur plus conviviale, suivez les conseils de jonmiddleton et spécifiez une page 404 personnalisée.

2
Nick Johnson

Je ne peux pas commenter la réponse de jonmiddleton, mais les réponses d'erreur personnalisées concernent les erreurs propres au moteur d'applications. Je ne vois pas de moyen de spécifier une page 404 personnalisée.

Django vous laisse spécifier un cependant.

0
zahanm

Mon approche consiste à gérer à la fois les redirections 404 et permanentes dans un gestionnaire catch all que je mets en dernier. Ceci est utile lorsque je modifie l'application et que je renomme/substitue des URL:

app = webapp2.WSGIApplication([
    ...
    ...
    ('/.*', ErrorsHandler)
], debug=True)


class ErrorsHandler(webapp2.RequestHandler):
    def get(self):
        p = self.request.path_qs
        if p in ['/index.html', 'resources-that-I-removed']:  
            return self.redirect('/and-substituted-with-this', permanent=True)
        else: 
            self.error(404)
            template = jinja_environment.get_template('404.html')
            context =  {
                'page_title': '404',
            }
            self.response.out.write(template.render(context))
0
JackNova