Reputation: 193
I logically want to connect a user defined exception with general exception handling. Firstly, it should be checked whether the user defined exception is triggered. If it is not triggered, but another exception occurs, I want to print the exception information by get_exception_info()
.
I have the following code:
class TestException(Exception):
pass
def get_exception_info():
try:
exception_type, exception_value, exception_traceback = sys.exc_info()
file_name, line_number, procedure_name, line_code = traceback.extract_tb(exception_traceback)[-1] #this line is properly indented in my file
exception_info = ''.join('[Time Stamp]: '
+ str(time.strftime('%d-%m-%Y %I:%M:%S %p'))
+ '' + '[File Name]: ' + str(file_name) + ' '
+ '[Procedure Name]: ' + str(procedure_name) + ' '
+ '[Error Message]: ' + str(exception_value) + ' '
+ '[Error Type]: ' + str(exception_type) + ' '
+ '[Line Number]: ' + str(line_number) + ' '
+ '[Line Code]: ' + str(line_code))
return exception_info
except:
pass
def test_func(x):
try:
if x > 0:
raise TestException('wrong')
elif x < 0:
raise TestException('right')
else:
pass
except TestException as e:
print(e)
except Exception:
exception_info = get_exception_info()
print(exception_info)
finally:
pass
test_func(a)
Theoretically, this would cause an Exception and it should print out the result of get_exception_info()
. However I just get "NameError: name 'a' is not defined.
What am I doing wrong? And, more importantly probably, is this the right way to archieve my goal?
Thank you!
Upvotes: 0
Views: 235
Reputation: 3907
The error indicates that the value a
which you are passing into test_func()
is not defined.
Add a line defining a
, e.g.:
# ...
a = "hello"
test_func(a)
For your code to work, you also need to import time
, traceback
, and sys
. I would also suggest not catching exceptions inside get_exception_info()
, as this may hide exceptions that you actually want to see, i.e.:
import time
import traceback
import sys
class TestException(Exception):
pass
def get_exception_info():
exception_type, exception_value, exception_traceback = sys.exc_info()
file_name, line_number, procedure_name, line_code = traceback.extract_tb(exception_traceback)[-1]
exception_info = ' '.join([
'[Time Stamp]:',
time.strftime('%d-%m-%Y %I:%M:%S %p'),
'[File Name]:',
file_name,
'[Procedure Name]:',
procedure_name,
'[Error Message]:',
str(exception_value),
'[Error Type]:',
str(exception_type),
'[Line Number]:',
str(line_number),
'[Line Code]:',
line_code,
])
return exception_info
# ...
It sounds like the question revolves around how to catch an undefined variable (a
in this case).
In that case, I would suggest adding a try
-except
block around the function call, e.g.:
try:
test_func(a)
except Exception:
exception_info = get_exception_info()
print(exception_info)
When a
is undefined, this will generate something along the lines of:
[Time Stamp]: 13-06-2021 10:44:31 AM [File Name]: /path/to/sf_exc.py [Procedure Name]: <module> [Error Message]: name 'a' is not defined [Error Type]: <class 'NameError'> [Line Number]: 76 [Line Code]: test_func(a)
As a general remark, instead of manually formatting the error message, I would use Python's logging
module which is powerful and gives a lot of flexibility when it comes to formatting different types of messages, using a custom Formatter
. In particular, Formatter
comes with methods that can be customised to treat exceptions and stack information.
Upvotes: 1