0

I'm using the output suppression contextmanager described in charleslparker's answer to this question: How to suppress console output in Python? - this works beautifully, but it's nested in a larger block of code (snippet below) dedicated to downloading files from a specific website, which utilizes a higher-level try/except block to catch connection errors. This should be simple, as described in a_guest's beautiful answer to this similar question: Catching an exception while using a Python 'with' statement - however, my problem is that I have an extra block of code (specifically, checking for matching file sizes locally and on the website) that needs to execute upon successful completion of the download, which is getting called every time the ConnectionError exception is raised. Basically, the exception registered within the contextmanager does not propagate upwards correctly, and the code deletes the partial files before restarting the process. I want the exception encountered by the download within the context manager to skip straight to the explicit exception block, and I am totally stuck on how to force that.

@contextmanager
def suppress_stdout():
    with open(os.devnull, "w") as devnull:
        old_stdout = sys.stdout
        sys.stdout = devnull
        try:  
            yield
        except (ConnectionErrorType1, ConnectionErrorType2):
            raise ConnectionError()
        finally:
            sys.stdout = old_stdout

while True:
    try:
        with suppress_stdout():
            <download from the website>
        if check_file_sizes:
            <get target file size>
            if download_size != target_size:
                <delete files and try again>

    except ConnectionErrorType1:
        <print error-specific message>
        raise ConnectionError()
    except ConnectionErrorType2:
        <print error-specific message>
        raise ConnectionError()
    except:
        print("Something happened but I don't know what")
        raise ConnectionError()

Any and all insight is appreciated, and I'm happy to provide further context or clarification as needed.

tashton
  • 59
  • 7
  • HAve you tried putting the try/except block *inside* the `with` statement? – match Jun 11 '21 at 21:24
  • I'm not entirely sure from the description what want, but be aware that a bare ``raise`` in an ``except`` block propagates *the exact same* exception handled. Then again, it looks to me like ``suppress_stdout`` should not handle any exception at all and merely use ``try:`` ``finally:`` to restore ``stdout``. – MisterMiyagi Jun 11 '21 at 21:29
  • @match I can't put the `try/except` inside the with statement because the exceptions output text to inform the user about what went wrong, and the with statement would that – tashton Jun 11 '21 at 23:41
  • @MisterMiyagi if I limit `stdout` to just `try/finally`, then the exception doesn't get passed upwards correctly. It registers as an unknown exception, which doesn't get read by the two ConnectionErrorType blocks – tashton Jun 11 '21 at 23:43
  • What is an unknown exception? A bare try/finally propagates exceptions unchanged (unless finally itself raises) so if suppress_stdout currently handles ConnectionErrorType1, then removing the handler should let ConnectionErrorType1 bubble up. – MisterMiyagi Jun 12 '21 at 11:46
  • I forgot to add the last exception (edited now)- it's a catch-all designed to let the user know something happened with the connection even if it doesn't recognize the specific error type (also useful for troubleshooting the development). Every exception caught by `suppress_stdout` does bubble upward, but they only reach the last exception (i.e. "something happened but I don't know what" gets printed every time). Plus, the rising exception doesn't skip over the `if check_file_size` section of code, which should only execute if no errors appear – tashton Jun 14 '21 at 14:17
  • Please provide a [mcve], i.e. a minimal but complete example that runs and reproduces the error without modification. There are multiple ways that small errors can give the behaviour you observe, but the missing parts are hiding which. – MisterMiyagi Jun 14 '21 at 14:23

0 Answers0