Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

getting the exception class name in python?

I want to generate a string in an exception handler that contains the name of the exception, and any arguments passed...oretty much the final output that one gets with Traceback.

For example, if raise bar.FnordError("message") is called, in the exception handler, I want to produce the string: "bar.FnordError: message"

I want it to work for built in exceptions, as well as exceptions in the current and other modules. This is what I came up with, but it doesn't seem very pythonic.

def this_is_lame(err):
    if type(err).__module__ in ['__main__', 'builtins']:
        return "{}: {}".format(type(err).__name__, err)
    else:
        return "{}.{}: {}".format(type(err).__module__, type(err).__name__, err)

I've dug through the BaseException C code in python, and the Traceback standard library. I seem to be missing the correct "nice" accessor.

Is BaseException.__format__ documented anywhere? Are there escapes for it?

I've played around in the interpreter and nothing quite gives me what I want.

import sys
import traceback

import bar

try:
    raise bar.FnordError("message")
except Exception as err:
    print(type(err))
    print(repr(err))
    print(type(err).__module__)
    print(type(err).__name__)
    print(err)
    print("this is what I want: '{}'".format(this_is_lame(err)))

print()

try:
    raise ValueError("message")
except Exception as err:
    print(type(err))
    print(repr(err))
    print(type(err).__module__)
    print(type(err).__name__)
    print("this is what I want: '{}'".format(this_is_lame(err)))

which produces:

$ python foo.py
<class 'bar.FnordError'>
FnordError('message',)
bar
FnordError
message
this is what I want: 'bar.FnordError: message'

<class 'ValueError'>
ValueError('message',)
builtins
ValueError
this is what I want: 'ValueError: message'
like image 685
Paul T. Avatar asked Apr 28 '16 17:04

Paul T.


People also ask

How do I get the exception name?

Using printStackTrace() method − It print the name of the exception, description and complete stack trace including the line where exception occurred. Using toString() method − It prints the name and description of the exception. Using getMessage() method − Mostly used. It prints the description of the exception.

How do I get exception details in Python?

In Python, exceptions can be handled using a try statement. The critical operation which can raise an exception is placed inside the try clause. The code that handles the exceptions is written in the except clause. We can thus choose what operations to perform once we have caught the exception.

How do I print an exception type?

If you are going to print the exception, it is better to use print(repr(e)) ; the base Exception. __str__ implementation only returns the exception message, not the type. Or, use the traceback module, which has methods for printing the current exception, formatted, or the full traceback.

Is exception a class in Python?

In Python, all exceptions must be instances of a class that derives from BaseException . In a try statement with an except clause that mentions a particular class, that clause also handles any exception classes derived from that class (but not exception classes from which it is derived).


1 Answers

There's no "nice" accessor. Python itself does something pretty similar to what you're doing in the default sys.excepthook, although exceptions defined in __main__ print as __main__.WhateverException.

If you want to see how Python itself does it, on Python 2, the check happens in PyErr_Display, which checks strcmp(modstr, "exceptions"):

moduleName = PyObject_GetAttrString(exception, "__module__");
if (moduleName == NULL)
    err = PyFile_WriteString("<unknown>", f);
else {
    char* modstr = PyString_AsString(moduleName);
    if (modstr && strcmp(modstr, "exceptions"))
    {
        err = PyFile_WriteString(modstr, f);
        err += PyFile_WriteString(".", f);
    }
    Py_DECREF(moduleName);
}

On Python 3, print_exception checks _PyUnicode_CompareWithId(moduleName, &PyId_builtins).

moduleName = _PyObject_GetAttrId(type, &PyId___module__);
if (moduleName == NULL || !PyUnicode_Check(moduleName))
{
    Py_XDECREF(moduleName);
    err = PyFile_WriteString("<unknown>", f);
}
else {
    if (_PyUnicode_CompareWithId(moduleName, &PyId_builtins) != 0)
    {
        err = PyFile_WriteObject(moduleName, f, Py_PRINT_RAW);
        err += PyFile_WriteString(".", f);
    }
    Py_DECREF(moduleName);
}
like image 128
user2357112 supports Monica Avatar answered Sep 22 '22 05:09

user2357112 supports Monica