I'm using python gammu library for sending sms. Sometimes something is wrong and I would like to handle exception. Descritpion of Exceptions is here: https://wammu.eu/docs/manual/python/exceptions.html#module-gammu.exception
I have a problem with getting and returning errors from such situations. I've printed:
print(sys.exc_info())
It has result:
(<class 'gammu.ERR_UNKNOWN'>, ERR_UNKNOWN({'Text': 'Nieznany błąd.', 'Where': 'SendSMS', 'Code': 27}), <traceback object at 0x740a6cd8>)
If i assign:
error_obj = sys.exc_info()
How can I get from it: Text, Code, and type ERROR(here is ERR_UKNOWN)?
I will grateful for help.
cls, exception, _ = sys.exc_info()
text = exception['Text'] # or exception.Text ?
code = exception['Code'] # or exception.Code ?
print(cls, text, code)
Also take a look at traceback module:
import traceback
try:
1/0
except ArithmeticError as e:
traceback.print_exc()
You should be able to use the args on the exception to get to the Text:
print(error_obj.args)
error_obj.args[0]['Text']
Related
A reproducible example:
import traceback
X = None
try:
X.text
except (TypeError, AttributeError) as e:
traceback.print_exc(e)
This will raise an error at traceback.print_exc(e):
TypeError: '>=' not supported between instances of 'AttributeError' and 'int'
Any suggestion why this happens?
print_exc doesn't take the exception object as an argument, it uses sys.exc_info() to obtain exception information. When you're passing it e, it's interpreting it as a positional argument for limit which expects a type int. I believe if you just remove the argument you'll get the result you're looking for.
traceback.print_exc documentation
Based on the documentation : Python Docs - traceback module
The first argument to traceback.print_exc isn't the exception, it is a depth limit of how many deep the traceback goes. You are hitting an exception within the traceback module itselse, since it expects the first argument to be a limit.
Your code needs to be :
import traceback
X = None
try:
X.text
except (TypeError, AttributeError) as e:
traceback.print_exc()
The exception data is kept as a thread global in sys.exc_info() which is what traceback.print_exc() uses.
I have a Django ORM query like this:
try:
specialization_object = Specialization.objects.get(name="My Test Specialization")
except Exception as ex:
print(ex)
When there occurs an exception then it prints "Specialization matching query does not exist.", but it does not print the line number. How can I trace the line number on which the exception or error occurred?
try this:
import logging
logger = logging.getLogger(__name__)
try:
specialization_object = Specialization.objects.get(name="My Test Specialization")
except Exception as ex:
logger.info(ex, exc_info=True) # exc_info will add traceback
further reading see here
If you can't for any reason use logging, There's the standard package traceback, and you can do something like:
traceback.print_exc(file=sys.stdout)
I have figured out a simple solution just now:
import traceback
try:
specialization_object = Specialization.objects.get(name="My Test Specialization")
except Exception as ex:
print(traceback.format_exc())
How can I get more information on the type of exception error ?
For example, in the code below I know the exception is gonna be ZeroDivisionError.
try:
print(1/0)
except ZeroDivisionError:
print("Error")
But I want to be able to get the information on the type of error without having to define it. I saw this example somewhere but it generates syntax error for me.
try:
return int(var)
except ValueError, Argument:
print "The argument does not contain numbers\n", Argument
What I am mainly looking for is something like
try:
// Do something
except:
// Print out an information on the type of error
try:
# Do something
except Exception as e:
print(e)
You can replace Exception with ZeroDivisionError if you wish.
You can use stacktrace to get all the info about error.
https://docs.python.org/2/library/traceback.html
import stacktrace
try:
// Do something
except:
print(traceback.format_exc())
I am trying to catch a warning that is raised as an error by applying the 'error' filter of warnings.simplefilter. A minimum working example is given below:
>>> import warnings
>>> warnings.simplefilter('error')
>>> try:
... warnings.warn('test')
... except UserWarning:
... raise ValueError
...
ValueError:
This works fine, but if I want to chain this so that the traceback from the warning is included, I get the following TypeError:
>>> import sys
>>> try:
... warnings.warn('test')
... except UserWarning:
... raise ValueError from sys.exc_info()[2]
...
TypeError: exception causes must derive from BaseException
It seems that even though I am raising a class derived from BaseException (i.e. the ValueError), the information from the traceback from the UserWarning seems to be tricking Python into thinking I am still raising the UserWarning.
Is this the expected behavior? If so, is there a good workaround?
I am on Python 3.4.3.
You are trying to use the traceback object as the exception:
raise ValueError from sys.exc_info()[2]
sys.exc_info() returns a tuple of (ExceptionType, exception_instance, traceback); you'd want index 1 here (remember Python counts indices from 0!):
raise ValueError from sys.exc_info()[1]
Much better, capture the exception instance in a variable directly:
try:
warnings.warn('test')
except UserWarning as warning:
raise ValueError from warning
That way you don't have to count out tuple indices.
When you set the warnings filter to 'error', the exceptions are subclasses of the Warning exception class, which inherits from Exception, see the Exception Hierachy section.
How can I get the full stack trace from the Exception object itself?
Consider the following code as reduced example of the problem:
last_exception = None
try:
raise Exception('foo failed')
except Exception as e:
last_exception = e
# this happens somewhere else, decoupled from the original raise
print_exception_stack_trace(last_exception)
Edit: I lied, sorry. e.__traceback__ is what you want.
try:
raise ValueError
except ValueError as e:
print( e.__traceback__ )
>c:/python31/pythonw -u "test.py"
<traceback object at 0x00C964B8>
>Exit code: 0
This is only valid in Python 3; you can't do it in earlier versions.