make sure we exit immediately if we fail to load the application.

While I'm here describe a more accurate error when it happens.

fix #508
This commit is contained in:
benoitc 2013-04-22 18:42:29 +02:00
parent 3ade8e8d78
commit 612f4125dd
3 changed files with 28 additions and 4 deletions

View File

@ -14,7 +14,7 @@ import sys
import time
import traceback
from gunicorn.errors import HaltServer
from gunicorn.errors import HaltServer, AppImportError
from gunicorn.pidfile import Pidfile
from gunicorn.sock import create_sockets
from gunicorn import util
@ -34,6 +34,9 @@ class Arbiter(object):
# this error code, the arbiter will terminate.
WORKER_BOOT_ERROR = 3
# A flag indicating if an application failed to be loaded
APP_LOAD_ERROR = 4
START_CTX = {}
LISTENERS = []
@ -435,6 +438,9 @@ class Arbiter(object):
if exitcode == self.WORKER_BOOT_ERROR:
reason = "Worker failed to boot."
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
if exitcode == self.APP_LOAD_ERROR:
reason = "App failed to load."
raise HaltServer(reason, self.APP_LOAD_ERROR)
worker = self.WORKERS.pop(wpid, None)
if not worker:
continue
@ -478,6 +484,13 @@ class Arbiter(object):
sys.exit(0)
except SystemExit:
raise
except AppImportError as e:
self.log.debug("Exception while loading the application: \n%s",
traceback.format_exc())
sys.stderr.write("%s\n" % e)
sys.stderr.flush()
sys.exit(self.APP_LOAD_ERROR)
except:
self.log.exception("Exception in worker process:\n%s",
traceback.format_exc())

View File

@ -15,3 +15,7 @@ class HaltServer(BaseException):
class ConfigError(BaseException):
""" Exception raised on config error """
class AppImportError(Exception):
""" Exception raised when loading an application """

View File

@ -18,6 +18,7 @@ import inspect
import errno
import warnings
from gunicorn.errors import AppImportError
from gunicorn.six import text_type, string_types
MAXFD = 1024
@ -358,11 +359,17 @@ def import_app(module):
raise
mod = sys.modules[module]
app = eval(obj, mod.__dict__)
try:
app = eval(obj, mod.__dict__)
except NameError:
raise AppImportError("Failed to find application: %r" % module)
if app is None:
raise ImportError("Failed to find application object: %r" % obj)
raise AppImportError("Failed to find application object: %r" % obj)
if not callable(app):
raise TypeError("Application object must be callable.")
raise AppImportError("Application object must be callable.")
return app