mirror of
https://github.com/frappe/gunicorn.git
synced 2026-01-14 11:09:11 +08:00
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:
parent
3ade8e8d78
commit
612f4125dd
@ -14,7 +14,7 @@ import sys
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
|
||||||
from gunicorn.errors import HaltServer
|
from gunicorn.errors import HaltServer, AppImportError
|
||||||
from gunicorn.pidfile import Pidfile
|
from gunicorn.pidfile import Pidfile
|
||||||
from gunicorn.sock import create_sockets
|
from gunicorn.sock import create_sockets
|
||||||
from gunicorn import util
|
from gunicorn import util
|
||||||
@ -34,6 +34,9 @@ class Arbiter(object):
|
|||||||
# this error code, the arbiter will terminate.
|
# this error code, the arbiter will terminate.
|
||||||
WORKER_BOOT_ERROR = 3
|
WORKER_BOOT_ERROR = 3
|
||||||
|
|
||||||
|
# A flag indicating if an application failed to be loaded
|
||||||
|
APP_LOAD_ERROR = 4
|
||||||
|
|
||||||
START_CTX = {}
|
START_CTX = {}
|
||||||
|
|
||||||
LISTENERS = []
|
LISTENERS = []
|
||||||
@ -435,6 +438,9 @@ class Arbiter(object):
|
|||||||
if exitcode == self.WORKER_BOOT_ERROR:
|
if exitcode == self.WORKER_BOOT_ERROR:
|
||||||
reason = "Worker failed to boot."
|
reason = "Worker failed to boot."
|
||||||
raise HaltServer(reason, self.WORKER_BOOT_ERROR)
|
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)
|
worker = self.WORKERS.pop(wpid, None)
|
||||||
if not worker:
|
if not worker:
|
||||||
continue
|
continue
|
||||||
@ -478,6 +484,13 @@ class Arbiter(object):
|
|||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
raise
|
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:
|
except:
|
||||||
self.log.exception("Exception in worker process:\n%s",
|
self.log.exception("Exception in worker process:\n%s",
|
||||||
traceback.format_exc())
|
traceback.format_exc())
|
||||||
|
|||||||
@ -15,3 +15,7 @@ class HaltServer(BaseException):
|
|||||||
|
|
||||||
class ConfigError(BaseException):
|
class ConfigError(BaseException):
|
||||||
""" Exception raised on config error """
|
""" Exception raised on config error """
|
||||||
|
|
||||||
|
|
||||||
|
class AppImportError(Exception):
|
||||||
|
""" Exception raised when loading an application """
|
||||||
|
|||||||
@ -18,6 +18,7 @@ import inspect
|
|||||||
import errno
|
import errno
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
from gunicorn.errors import AppImportError
|
||||||
from gunicorn.six import text_type, string_types
|
from gunicorn.six import text_type, string_types
|
||||||
|
|
||||||
MAXFD = 1024
|
MAXFD = 1024
|
||||||
@ -358,11 +359,17 @@ def import_app(module):
|
|||||||
raise
|
raise
|
||||||
|
|
||||||
mod = sys.modules[module]
|
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:
|
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):
|
if not callable(app):
|
||||||
raise TypeError("Application object must be callable.")
|
raise AppImportError("Application object must be callable.")
|
||||||
return app
|
return app
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user