diff --git a/r2/r2/commands.py b/r2/r2/commands.py index 454c8962c..892f9778d 100644 --- a/r2/r2/commands.py +++ b/r2/r2/commands.py @@ -26,6 +26,8 @@ import paste.fixture from paste.script import command from paste.deploy import loadapp +from r2.lib.log import RavenErrorReporter + class RunCommand(command.Command): max_args = 2 @@ -55,6 +57,8 @@ class RunCommand(command.Command): config_file = self.args[0] config_name = 'config:%s' % config_file + report_to_sentry = "REDDIT_ERRORS_TO_SENTRY" in os.environ + here_dir = os.getcwd() # Load locals and populate with objects for use in shell @@ -84,8 +88,14 @@ class RunCommand(command.Command): loaded_namespace = {} - if self.args[1:]: - execfile(self.args[1], loaded_namespace) + try: + if self.args[1:]: + execfile(self.args[1], loaded_namespace) - if self.options.command: - exec self.options.command in loaded_namespace + if self.options.command: + exec self.options.command in loaded_namespace + except Exception: + if report_to_sentry: + exc_info = sys.exc_info() + RavenErrorReporter.capture_exception(exc_info=exc_info) + raise diff --git a/r2/r2/lib/log.py b/r2/r2/lib/log.py index 7a2320088..1bd1802d5 100644 --- a/r2/r2/lib/log.py +++ b/r2/r2/lib/log.py @@ -187,11 +187,18 @@ class RavenErrorReporter(Reporter): ) return RAVEN_CLIENT - def report(self, exc_data): - if issubclass(exc_data.exception_type, get_operational_exceptions()): + @classmethod + def capture_exception(cls, exc_info=None): + if exc_info is None: + # if possible exc_info should be captured as close to the exception + # as possible and passed in because sys.exc_info() can give + # unexpected behavior + exc_info = sys.exc_info() + + if issubclass(exc_info[0], get_operational_exceptions()): return - client = self.get_raven_client() + client = cls.get_raven_client() if g.running_as_script: # scripts are run like: @@ -201,9 +208,9 @@ class RavenErrorReporter(Reporter): # either way sys.argv[-1] will tell us the entry point to the error culprit = 'script: "%s"' % sys.argv[-1] else: - self.add_http_context(client) - self.add_reddit_context(client) - self.add_user_context(client) + cls.add_http_context(client) + cls.add_reddit_context(client) + cls.add_user_context(client) routes_dict = request.environ["pylons.routes_dict"] controller = routes_dict.get("controller", "unknown") @@ -211,13 +218,19 @@ class RavenErrorReporter(Reporter): culprit = "%s.%s" % (controller, action) try: - client.captureException(data={ - "modules": self.get_module_versions(), - "culprit": culprit, - }) + client.captureException( + exc_info=exc_info, + data={ + "modules": cls.get_module_versions(), + "culprit": culprit, + }, + ) finally: client.context.clear() + def report(self, exc_data): + self.capture_exception() + def write_error_summary(error): """Log a single-line summary of the error for easy log grepping."""