def test_does_not_email_for_whitelisted_errors(self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine( "/site-packages/lib/doghouse/authentication.py", 7, "check_auth", 'raise errors.BadAuthenticationError("Something smells off...")' ) ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey( "lib/doghouse/authentication.py", 7, "check_auth", 'raise errors.BadAuthenticationError("Something smells off...")'): api.ErrorInfo(1, "*****@*****.**", "2017-07-30 00:00:00", False, "2020-01-01 00:00:00", is_known_error=True, last_error_data=req) }, self.handler.errors_seen.dict) self.assertEquals(None, self.smtp_stub.last_args)
def view_traceback(self, filename="", function_name="", text="", line_number="", timestamp=None): file_path = self._file_path_for_ms(int(timestamp) * 1000) if timestamp else None errdict = dict() if timestamp is None or self.errors_seen.get_path() == file_path: errdict = self.errors_seen.dict else: report = self.persistent_dict_cls(file_path) report.open() errdict = report.dict err_key = api.ErrorKey(filename=filename, function_name=function_name, text=text, line_number=line_number) err_info = errdict.get(err_key) datastr = "Not Found" if err_info: datastr = self._format_traceback(err_info.last_error_data) return """ <html> <head> <title>Flawless Traceback</title> </head> <body style='font-family: courier; font-size: 10pt'> {data} </body> </html> """.format(data=datastr)
def test_traces_up_stack_trace_for_errors_originating_from_building_blocks( self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine("/site-packages/coreservices/service.py", 7, "serve", "..."), api.StackLine( "/site-packages/apps/shopkick/doghouse/lib/base.py", 9, "_get_request_param", 'raise errors.BadRequestError("Missing param %s" % name)') ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/service.py", 7, "serve", "..."): api.ErrorInfo(1, "*****@*****.**", "2017-07-30 00:00:00", True, "2020-01-01 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict)
def test_records_error_only_once(self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine("/site-packages/coreservices/service.py", 7, "serve", "..."), api.StackLine("/site-packages/thirdparty/3rdparty_lib.py", 9, "call", "x") ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self._set_stub_time(datetime.datetime(2020, 1, 2)) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/service.py", 7, "serve", "..."): api.ErrorInfo(2, "*****@*****.**", "2017-07-30 00:00:00", True, "2020-01-02 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict) self.assertEqual(1, len(self.smtp_stub.args_list))
def test_doesnt_email_on_errors_before_cutoff_date(self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine("/site-packages/coreservices/service.py", 7, "serve", "..."), api.StackLine("/site-packages/thirdparty/3rdparty_lib.py", 9, "call", "x") ], exception_message="email text", hostname="localhost", ) self.popen_stub.stdout = StringIO.StringIO( "75563df6e9d1efe44b48f6643fde9ebbd822b0c5 25 25 1\n" "author John Egan\n" "author-mail <*****@*****.**>\n" "author-time %d\n" "author-tz -0800\n" % int(time.mktime(datetime.datetime(2009, 7, 30).timetuple()))) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/service.py", 7, "serve", "..."): api.ErrorInfo(1, "*****@*****.**", "2009-07-30 00:00:00", False, "2020-01-01 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict) self.assertEqual(None, self.smtp_stub.last_args)
def test_doesnt_report_errors_under_threshold(self): self.test_config.report_error_threshold = 2 req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine("/site-packages/coreservices/service.py", 7, "serve", "..."), api.StackLine("/site-packages/thirdparty/3rdparty_lib.py", 9, "call", "x") ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/service.py", 7, "serve", "..."): api.ErrorInfo(1, "*****@*****.**", "2017-07-30 00:00:00", False, "2020-01-01 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict) self.assertEquals(None, self.smtp_stub.last_args)
def _blame_line(self, traceback): '''Figures out which line in traceback is to blame for the error. Returns a 3-tuple of (api.ErrorKey, StackTraceEntry, [email recipients])''' key = None blamed_entry = None email_recipients = [] for stack_line in traceback: line_type = self._get_line_type(stack_line) if line_type == LineTypeEnum.THIRDPARTY_WHITELIST: return None, None, None elif line_type in [LineTypeEnum.DEFAULT, LineTypeEnum.KNOWN_ERROR]: filepath = self.extract_base_path_pattern.match( stack_line.filename).group(1) entry = StackTraceEntry(filepath, stack_line.function_name, stack_line.text) blamed_entry = entry key = api.ErrorKey(filepath, stack_line.line_number, stack_line.function_name, stack_line.text) if filepath in self.watch_all_errors: email_recipients.extend(self.watch_all_errors[filepath]) return (key, blamed_entry, email_recipients)
def test_records_error_with_thrift_in_file_name(self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/coreservices/thrift_file.py", 7, "serve", "..."), api.StackLine("/site-packages/thirdparty/3rdparty_lib.py", 9, "call", "x") ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/thrift_file.py", 7, "serve", "..."): api.ErrorInfo(1, "*****@*****.**", "2017-07-30 00:00:00", True, "2020-01-01 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict)
def test_records_error(self): req = api.RecordErrorRequest( traceback=[ api.StackLine("/site-packages/lib/test.py", 5, "test_func", "code"), api.StackLine("/site-packages/coreservices/service.py", 7, "serve", "..."), api.StackLine("/site-packages/thirdparty/3rdparty_lib.py", 9, "call", "x") ], exception_message="email text", hostname="localhost", ) self.handler.record_error(req.dumps()) self.assertDictEquals( { api.ErrorKey("coreservices/service.py", 7, "serve", "..."): api.ErrorInfo(1, "*****@*****.**", "2017-07-30 00:00:00", True, "2020-01-01 00:00:00", is_known_error=False, last_error_data=req) }, self.handler.errors_seen.dict) self.assertEqual([ "git", "--git-dir=/tmp/.git", "--work-tree=/tmp", "blame", "-p", "/tmp/coreservices/service.py", "-L", "7,+1" ], self.popen_stub.last_args) self.assertEmailEquals( dict(to_addresses=["*****@*****.**"], from_address="*****@*****.**", subject="Error on localhost in coreservices/service.py", body="email text", smtp_server_host_port=None), self.smtp_stub.last_args)