54

I've seen similar questions to this one but none of them really address the trackback. If I have a class like so

class Stop_if_no_then():
    def __init__(self, value one, operator, value_two, then, line_or_label, line_number):
        self._firstvalue = value_one
        self._secondvalue = value_two
        self._operator = operator
        self._gohere = line_or_label
        self._then = then
        self._line_number = line_number

    def execute(self, OtherClass):
        "code comparing the first two values and making changes etc"

What I want my execute method to be able to do is if self._then is not equal to the string "THEN" (in allcaps) then I want it to raise a custom error message and terminate the whole program while also not showing a traceback.

If the error is encountered the only thing that should print out would look something like (I'm using 3 as an example, formatting is not a problem) this.

`Syntax Error (Line 3): No -THEN- present in the statement.`

I'm not very picky about it actually being an exception class object, so there's no issue in that aspect. Since I will be using this in a while loop, simple if, elif just repeats the message over and over (because obviously I am not closing the loop). I have seen sys.exit() but that also prints out a giant block of red text, unless I am not using it correctly. I don't want to catch the exception in my loop because there are other classes in the same module in which I need to implement something like this.

user1251007
  • 15,891
  • 14
  • 50
  • 76
user2560035
  • 701
  • 2
  • 6
  • 12

7 Answers7

72

You can turn off the traceback by limiting its depth.

Python 2.x

import sys
sys.tracebacklimit = 0

Python 3.x

In Python 3.5.2 and 3.6.1, setting tracebacklimit to 0 does not seem to have the intended effect. This is a known bug. Note that -1 doesn't work either. Setting it to None does however seem to work, at least for now.

In Python 3.6.2 and above you should set tracebacklimit to 0 or -1, as setting it to None does not disable the traceback output.

Python 3.6.1 and below results:

>>> import sys

>>> sys.tracebacklimit = 0
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

>>> sys.tracebacklimit = -1
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

>>> sys.tracebacklimit = None
>>> raise Exception
Exception

Python 3.6.2 and above results:

>>> import sys

>>> sys.tracebacklimit = 0
>>> raise Exception
Exception

>>> sys.tracebacklimit = -1
>>> raise Exception
Exception

>>> sys.tracebacklimit = None
>>> raise Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
Exception

Nevertheless, for better or worse, if multiple exceptions are raised, they can all still be printed. For example:

socket.gaierror: [Errno -2] Name or service not known

During handling of the above exception, another exception occurred:

urllib.error.URLError: <urlopen error [Errno -2] Name or service not known>
rustyMagnet
  • 3,479
  • 1
  • 31
  • 41
Marco Costa
  • 879
  • 1
  • 7
  • 9
  • 16
    `sys.tracebacklimit = 0` now works fine with Python 3.7. `sys.tracebacklimit = None` did not work in my case. – J D Jun 14 '19 at 12:22
  • `>>> sys.tracebacklimit = 0 >>> raise TypeError('asdas')` Output: `TypeError: asdas` – Charalamm Oct 04 '21 at 06:07
33

You can use SystemExit exception:

except Exception as err:
    raise SystemExit(err)

See the documentation on SystemExit for more details.

MisterMiyagi
  • 44,374
  • 10
  • 104
  • 119
user3487934
  • 431
  • 4
  • 3
18

You can use a try: and then except Exception as inst: What that will do is give you your error message in a variable named inst and you can print out the arguments on the error with inst.args. Try printing it out and seeing what happens, and is any item in inst.args is the one you are looking for.

EDIT Here is an example I tried with pythons IDLE:

>>> try:
    open("epik.sjj")
except Exception as inst:
    d = inst


>>> d
FileNotFoundError(2, 'No such file or directory')
>>> d.args
(2, 'No such file or directory')
>>> d.args[1]
'No such file or directory'
>>> 

EDIT 2: as for closing the program you can always raise and error or you can use sys.exit()

The-IT
  • 660
  • 8
  • 19
  • What is the "2" in d.args and is the error message "No such file or directory' customizeable (if I created my own Exception class object)? – user2560035 Jul 22 '13 at 10:51
  • Honestly, I don't know what the 2 is but it's not important. I'm showing you how to find the error message yourself. And the "No such file or directory" is a string which you can put into a variable and then do what ever you want to with. `errorMessage = d.args[1]` – The-IT Jul 22 '13 at 10:55
  • The actual error for that specific line of code is `FileNotFoundError: [Errno 2] No such file or directory: 'epik.sjj'` so that's where to 2 came from. the `.args` is a tuple of all the parts of the error. – The-IT Jul 22 '13 at 10:58
  • Why not just a simple `print('blah-blah-blah')` instead of `d = inst'? – blablatros Jul 22 '13 at 10:59
  • Also if I do sys.exit() or raise an exception that gives me a traceback. Is there no way to get rid of the traceback? or make it not show up – user2560035 Jul 22 '13 at 11:00
  • the `d = inst` is just me showing how to capture an error into a variable, in this case named `d`. You can do what ever you want is that part of the code. My aim to show how you can get an error message as a string using `try` and `except` statements (which are used for catching errors. – The-IT Jul 22 '13 at 11:01
  • @user2560035 I'm sorry, I assumed you new how error excpetions worked in python. I suggest you have a read up: http://docs.python.org/2/tutorial/errors.html. If you have any questions, feal free to ask me. – The-IT Jul 22 '13 at 11:03
  • 1
    @The-IT The `2` first argument comes from the [`errno` module](https://docs.python.org/3/library/errno.html) and is the value of `errno.ENOENT`. The second argument `'No such file or directory'` is the output of `os.strerror(errno.ENOENT)`. – MT0 Jul 08 '20 at 00:39
14

The cleanest way that I know is to use sys.excepthook.

You implement a three argument function that accepts type, value, and traceback and does whatever you like (say, only prints the value) and assign that function to sys.excepthook.

Here is an example:

import sys

def excepthook(type, value, traceback):
    print(value)

sys.excepthook = excepthook

raise ValueError('hello')

This is available in both python 2 and python 3.

Mark Veltzer
  • 1,394
  • 15
  • 20
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/156936/discussion-between-egmusic-and-mark-veltzer). – EgMusic Oct 17 '17 at 16:29
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/157117/discussion-between-mark-veltzer-and-egmusic). – Mark Veltzer Oct 20 '17 at 05:57
  • Would there be a way to print only the value in the console, but full traceback in a log at the same time? – erocoar Dec 02 '17 at 12:05
  • Sure. You can use the traceback module and do what ever you want in the 'execepthook' function. – Mark Veltzer Dec 02 '17 at 13:52
8

If you want to get rid of any traceback for customs exceptions and have line number, you can do this trick

Python 3

import sys
import inspect

class NoTraceBackWithLineNumber(Exception):
    def __init__(self, msg):
        try:
            ln = sys.exc_info()[-1].tb_lineno
        except AttributeError:
            ln = inspect.currentframe().f_back.f_lineno
        self.args = "{0.__name__} (line {1}): {2}".format(type(self), ln, msg),
        sys.exit(self)

class MyNewError(NoTraceBackWithLineNumber):
    pass

raise MyNewError("Now TraceBack Is Gone")

Will give this output, and make the raise keyword useless

MyNewError (line 16): Now TraceBack Is Gone
creuilcreuil
  • 81
  • 1
  • 4
7

"Exception chaining can be disabled by using from None " - Python docs

>>> try:
...     open('database.sqlite')
... except IOError:
...     raise RuntimeError from None

Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
patel deven
  • 630
  • 7
  • 9
3

In general, if you want to catch any exception except SystemExit, and exit with the exception's message without the traceback, define your main function as below:

>>> import sys

>>> def main():
...     try:
...         # Run your program from here.
...         raise RandomException  # For testing
...     except (Exception, KeyboardInterrupt) as exc:
...         sys.exit(exc)
... 
>>> main()
name 'RandomException' is not defined

$ echo $?
1

Note that in the case of multiple exceptions being raised, only one message is printed.

This answer is meant to improve upon the one by The-IT.

Community
  • 1
  • 1
Asclepius
  • 57,944
  • 17
  • 167
  • 143