Pregunta

He configurado un sitio web estático en GAE utilizando sugerencias encontradas en otros lugares, pero no puedo encontrar la manera de devolver un error 404. Mi archivo app.yaml se parece a

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

- url: /
  static_dir: static

con todos los archivos estáticos html / jpg almacenados en el directorio estático. Lo anterior funciona para archivos que existen, pero devuelve un archivo de longitud nula si no es así. La respuesta es probablemente escribir una secuencia de comandos de Python para devolver un error 404, pero ¿cómo configurar las cosas para servir los archivos estáticos que existen pero ejecutar la secuencia de comandos para los archivos que no lo hacen?

Aquí está el registro de buscar un archivo inexistente (nosuch.html) en el servidor de aplicaciones de desarrollo:

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 -
¿Fue útil?

Solución

Debe registrar un controlador de script general. Agregue esto al final de su app.yaml:

- url: /.*
  script: main.py

En main.py deberás poner este código:

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 __name__ == "__main__":
    main()

Reemplace <Your 404 error html page> con algo significativo. O mejor use una plantilla, puede leer cómo hacerlo aquí .

Avíseme si tiene problemas para configurar esto.

Otros consejos

El

motor de aplicaciones de Google ahora tiene Respuestas de error personalizadas

para que ahora pueda agregar una sección error_handlers a su app.yaml, como en este ejemplo:

error_handlers:

- file: default_error.html

- error_code: over_quota
    file: over_quota.html

Una manera significativamente más simple de hacer esto sin requerir ningún ciclo de CPU es colocar este controlador en la parte inferior de su app.yaml

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

Esto le permite colocar un archivo 404.html estático en su directorio de vistas. No es necesario un controlador de python. Cualquier cosa que no se maneje en tu app.yaml ya golpeará eso.

Puede crear una función para manejar sus errores para cualquiera de los códigos de estado. Su caso es 404, defina una función como esta:

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

Puede pasar cualquier cosa: HTML / texto plano / plantillas en la función response.out.write. Ahora, agregue la siguiente declaración después de su app declaración.

app.error_handlers[404] = Handle404

Esto funcionó para mí.

webapp2 proporciona el diccionario error_handlers que puede usar para servir páginas de error personalizadas. Ejemplo a continuación:

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

Más detalles están disponibles en las páginas de documentación de <=>: http : //webapp-improved.appspot.com/guide/app.html#error-handlers

dev_appserver ya está devolviendo respuestas 404 para cualquier cosa que no coincida con el mapeo, o con el mapeo pero que no existe. La respuesta 404 en sí misma no tiene cuerpo, pero sigue siendo 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 desea devolver una página de error más fácil de usar, siga los consejos de jonmiddleton y especifique una página 404 personalizada.

He revisado todas las respuestas anteriores y he utilizado las siguientes al final como la solución 404 más universal:

Agregue este enlace al final de app.yaml

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

y crea 404.py con el siguiente contenido

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)

Esto mostrará el contenido del archivo 404.html con código de error 404.

La ventaja de esta solución es la simplicidad, la corrección del comportamiento y la flexibilidad, ya que permite utilizar un archivo estático Custom Error Responses como contenido de la página de error.

También quiero advertir contra algunas de las soluciones sugeridas anteriormente.

  • <=> no funciona con error 404
  • Tampoco use archivos estáticos, ya que devolverían 200 en lugar de error 404. Esto puede causar mucho dolor de cabeza por delante.

No puedo comentar sobre la respuesta de jonmiddleton, pero las respuestas de error personalizadas son para errores específicos del motor de la aplicación. No veo una manera de especificar una página 404 personalizada.

Django le permite especifique uno.

Mi enfoque es manejar las redirecciones 404 y permanentes en un controlador catch all que puse como el último. Esto es útil cuando rediseño y aplico y cambio el nombre / sustituyo las 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))
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top