Anirban Chakraborty
Anirban Chakraborty

Reputation: 781

Where is the error traceback message for unhandled exceptions written - sys.stdout or sys.stderr or somewhere else? (in Python)

As per my understanding, in Python, sys.stdin, sys.stdout and sys.stderr are the file objects linked to the standard input, output and error streams respectively. Now the stdout and stderr file objects can be changed to arbitrary files in order to log them somewhere else apart from the console.

I did this, and everything worked fine. However, I noticed that in case of unhandled exceptions, an error traceback message is thrown which was being displayed in the console. That indicates that this traceback message was not directed to stdout or stderr.

Please find below the code that was run:

import sys

old_stdout, old_stderr = sys.stdout, sys.stderr
sys.stdout, sys.stderr = open('Outfile.txt', 'w'), open('Errorlog.txt', 'w')

try:
    name = input('Enter your name: ')
    print('Hi %s' % name)
    age = int(input('What is your age? '))
    if age <= 0:
        raise ValueError('Age cannot be 0.')
    else:
        print('So how does it feel to be %d' % age)
# except Exception as e:
#     print(e)
finally:
    sys.stderr.close(), sys.stdout.close()
    sys.stderr, sys.stdout = old_stderr, old_stdout

When the except block is present, the error message is getting printed as per expectation in stdout (i.e., Outfile.txt). When the except block is commented out to make it an unhandled exception, the traceback is getting printed in the console as below:

F:\> python.exe Change_stdout_stderr_to_log_files.py
Anirban
0
Traceback (most recent call last):
  File "Change_stdout_stderr_to_log_files.py", line 18, in <module>
    raise ValueError('Age cannot be 0.')
ValueError: Age cannot be 0.

F:\> 

Nothing is printed regarding the error in stdout or stderr though. So where is this error message actually directed?

Upvotes: 0

Views: 560

Answers (1)

tripleee
tripleee

Reputation: 189739

You have redirected your program's standard error to somewhere else, but Python's standard error is still connected to your terminal.

Observe:

bash$ python -c 'import sys; sys.stderr = open("/dev/null"); raise ValueError("I am the walrus")'
bash$ python -c '=' 2>/dev/null
bash$ python -c 'import sys; sys.stderr = open("/dev/null"); raise ValueError("I am the walrus"); ='
  File "<string>", line 1
    import sys; sys.stderr = open("/dev/null"); raise ValueError("I am the walrus"); =
                                                                                     ^
SyntaxError: invalid syntax

Upvotes: 1

Related Questions