Skip to content

simulator

SuppressLogsUntilError

Suppress stdout/stderr logs until an error occurs, at which point dump everything.

Source code in OmniGibson/omnigibson/simulator.py
class SuppressLogsUntilError:
    """
    Suppress stdout/stderr logs until an error occurs, at which point dump everything.
    """

    def __init__(self, _):
        self._old_stdout = None
        self._old_stderr = None
        self._tmpfile = None
        self._tmppath = None
        self._running = False

    def __enter__(self):
        # Temp file to buffer logs
        self._tmpfile = tempfile.NamedTemporaryFile(delete=False, mode="w+")
        self._tmppath = self._tmpfile.name
        self._tmpfile.close()

        # Save original fds
        sys.stdout.flush()
        sys.stderr.flush()
        self._old_stdout = os.dup(1)
        self._old_stderr = os.dup(2)

        # Redirect stdout/stderr → temp file
        fd = os.open(self._tmppath, os.O_WRONLY | os.O_APPEND)
        os.dup2(fd, 1)
        os.dup2(fd, 2)
        os.close(fd)

        # Start background reader
        self._running = True

        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # Stop background reader
        self._running = False

        # Restore stdout/stderr
        sys.stdout.flush()
        sys.stderr.flush()
        os.dup2(self._old_stdout, 1)
        os.dup2(self._old_stderr, 2)
        os.close(self._old_stdout)
        os.close(self._old_stderr)

        # On error → dump everything + traceback
        if exc_type is not None:
            print("\n=== Isaac Sim logs (dump on error) ===\n")
            with open(self._tmppath, "r") as f:
                print(f.read())
            print("=== End of Isaac Sim logs ===\n")

            print("Python traceback:\n")
            traceback.print_exception(exc_type, exc_val, exc_tb)

        # Cleanup
        try:
            os.remove(self._tmppath)
        except OSError:
            pass

        return False  # let exception propagate