<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def run(self):
 """ Runs the task. This fires the ``on_start`` hook function first (if present), passing the task itself. Then it runs the target function supplied via ``Task.to_call`` with its arguments & stores the result. If the target function succeeded, the ``on_success`` hook function is called, passing both the task & the result to it. If the target function failed (threw an exception), the ``on_error`` hook function is called, passing both the task & the exception to it. Then the exception is re-raised. Finally, the result is returned. """

        if self.on_start:
            self.on_start(self)

        try:
            result = self.func(*self.func_args, **self.func_kwargs)
        except Exception as err:
            self.to_failed()

            if self.on_error:
                self.on_error(self, err)

            raise

        self.to_success()

        if self.on_success:
            self.on_success(self, result)

        return result