0

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!

1 Answer 1

1

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)

EDIT:

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
# ...

EDIT II:

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)

Comment

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.

Sign up to request clarification or add additional context in comments.

6 Comments

I know, this is intentional. I want to trigger an exception, but I want that get_exception_info() is executed within that exception..
Yes, I thought so. If you pass in a string, the comparison attempt (x >0) will raise a TypeError with '>' not supported between instances of 'str' and 'int'.
Hey @p3j4p5, I forgot to list my imports, I did them of course. But what I don't understand is what does (x>0) raise a TypeError? How I understood Exceptions up to now is that if an exception occurs, the function looks whether there is a specificly defined procedure for the current exception, and, if not, would just trigger the usual Exception output. However, except Exception should catch the TypeError, as TypeError is a subclass of Exception, isn't it?
@Paul1911 - Yes, that's correct. When you pass in a = "hello" (i.e. a is a string), the comparison x > 0 will raise a TypeError exception because you are trying to compare a string to an integer, which is not defined. Since this comparison is inside the try-except block it will be caught by except Exception and should print the exception_info message as you've defined it. In other words, passing in a string into test_func() is just a way to trigger and test the logic you've defined.
I'm starting to understand where you're coming from. I'm not an expert on this but I would guess, the evaluation of the variable a happens around the time a new stack frame is created for the call to test_func(). In other words, if you wanted to catch an exception raised in this case, you'd have to put the function call into a try-except block. I've updated the answer accordingly.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.