# Buggy code
def _work(self):
    while True:
        self._change_event.wait()

        now = time.time()
        delta = now - self._last_update
        additional_wait_time = self._interval - delta
        if additional_wait_time > 0:
            time.sleep(additional_wait_time)

        with self._state_lock:
            data = self.get_current_data()
            self._update_callback(data)
            self._last_update = time.time()
            self._change_event.clear()


# Traceback (AttributeError)
2018-07-05 05:17:16,231 - octoprint.util.comm - INFO - Externally triggered heatup detected
2018-07-05 05:18:34,517 - octoprint.util.comm - INFO - Printer seems to support the busy protocol, telling it to set the busy interval to our "communicationBusy" timeout - 1s = 2s
2018-07-05 05:19:27,589 - octoprint.util.comm - INFO - Timeout while in an active heatup, considering heatup to be over.
2018-07-05 05:19:30,594 - octoprint.util.comm - INFO - Communication timeout while idle, trying to trigger response from printer.
2018-07-05 05:19:32,426 - octoprint.util.comm - INFO - Changing monitoring state from "Operational" to "Printing from SD"
2018-07-05 05:19:32,512 - octoprint.plugins.Octoslack - ERROR - Error processing event: PrintStarted, Error: 'Printer' object has no attribute '_estimator'
Traceback (most recent call last):
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_Octoslack/__init__.py", line 591, in handle_event
self.process_slack_event(event, event_settings, channel_override, payload)
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint_Octoslack/__init__.py", line 648, in process_slack_event
printer_data = self._printer.get_current_data()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/server/__init__.py", line 384, in wrapper
return f(*args, **kwargs)
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/printer/standard.py", line 565, in get_current_data
return util.thaw_frozendict(self._stateMonitor.get_current_data())
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/printer/standard.py", line 1326, in get_current_data
self._progress = self._get_current_progress()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/printer/standard.py", line 1255, in _get_current_progress
return self._on_get_progress()
File "/home/pi/oprint/local/lib/python2.7/site-packages/octoprint/printer/standard.py", line 773, in _updateProgressDataCallback
printTimeLeft, printTimeLeftOrigin = self._estimator.estimate(progress,
AttributeError: 'Printer' object has no attribute '_estimator'
2018-07-05 05:20:41,680 - octoprint.util.comm - INFO - Communication timeout while printing, trying to trigger response from printer.
2018-07-05 05:20:41,718 - octoprint.util.comm - INFO - Changing monitoring state from "Printing from SD" to "Cancelling"
2018-07-05 05:20:41,880 - octoprint.util.comm - INFO - Changing monitoring state from "Cancelling" to "Operational"
2018-07-05 05:21:35,678 - octoprint.server.api.system - INFO - Performing command for core:restart: sudo service octoprint restart

# Fixed code
def _work(self):
    try:
        while True:
            self._change_event.wait()

            now = time.time()
            delta = now - self._last_update
            additional_wait_time = self._interval - delta
            if additional_wait_time > 0:
                time.sleep(additional_wait_time)

            with self._state_lock:
                data = self.get_current_data()
                self._update_callback(data)
                self._last_update = time.time()
                self._change_event.clear()
    except:
        logging.getLogger(__name__).exception(
            "Looks like something crashed inside the state update worker. Please report this on the OctoPrint issue tracker (make sure to include logs!)"
        )