287

I would like to know how to I exit from Python without having an traceback dump on the output.

I still want want to be able to return an error code but I do not want to display the traceback log.

I want to be able to exit using exit(number) without trace but in case of an Exception (not an exit) I want the trace.

the Tin Man
  • 150,910
  • 39
  • 198
  • 279
sorin
  • 137,198
  • 150
  • 472
  • 707
  • 8
    sys.exit() stops execution without printing a backtrace, raising an Exception does... your question describes exactly what the default behavior is, so don't change anything. – Luper Rouch Jul 27 '09 at 17:43
  • @Luper It is very easy to check that sys.exit() throws SystemExit! – Val Oct 01 '12 at 18:45
  • 4
    I said it doesn't print a traceback, not that it doesn't raise an exception. – Luper Rouch Oct 02 '12 at 05:45
  • I think that this really answers the question you asked: http://stackoverflow.com/questions/173278/is-there-a-way-to-prevent-a-systemexit-exception-raised-from-sys-exit-from-bei – Stefan Nov 20 '12 at 19:39
  • 2
    Is this question specifically for Jython 2.4 or something like that? Because for modern versions of Python (even in 2009, when that meant CPython 2.6 and 3.1, Jython 2.5, and IronPython 2.6), the question makes no sense, and the top answers are wrong. – abarnert Sep 28 '14 at 02:18

10 Answers10

307

You are presumably encountering an exception and the program is exiting because of this (with a traceback). The first thing to do therefore is to catch that exception, before exiting cleanly (maybe with a message, example given).

Try something like this in your main routine:

import sys, traceback

def main():
    try:
        do main program stuff here
        ....
    except KeyboardInterrupt:
        print "Shutdown requested...exiting"
    except Exception:
        traceback.print_exc(file=sys.stdout)
    sys.exit(0)

if __name__ == "__main__":
    main()
martineau
  • 99,260
  • 22
  • 139
  • 249
jkp
  • 70,446
  • 25
  • 98
  • 102
  • 2
    There should be something like "from sys import exit" in the beginning. – rob Jul 27 '09 at 13:16
  • 1
    Hi Roberto: exit() is available without importing it, though you can also import it from sys. – jkp Jul 27 '09 at 13:23
  • Note that in older versions of Python (before 2.5) the 'exit' builtin was a simple non-callable string. – Marius Gedminas Jul 27 '09 at 18:57
  • 11
    If sys.exit() is called in "main program stuff", the code above throws away the value passed to sys.exit. Notice that sys.exit raises SystemExit and the variable "e" will contain the exit code. – bstpierre Jul 27 '09 at 21:52
  • 5
    i would suggest printing in stderr sys.stderr.write(msg) – vinilios Jan 17 '12 at 17:20
  • In Python 2.x you might want to change the `except Exception:` to a bare `except:` since it is possible for code to raise exceptions that do not inherit from the `Exception` base class. – martineau Jun 30 '12 at 20:07
  • 17
    I *strongly* suggest removing the lines from `except Exception:` to `sys.exit(0)`, inclusive. It is already the default behavior to print a traceback on all non-handled exceptions, and to exit after code ends, so why bother doing the same manually? – MestreLion Dec 05 '12 at 11:32
  • 6
    @jkp - Regarding your comment: `sys.exit()` should be used for programs. `exit()` is intended for interactive shells. See [The difference between exit() and sys.exit() in Python?](http://stackoverflow.com/questions/6501121/the-difference-between-exit-and-sys-exit-in-python). – ire_and_curses Jan 16 '13 at 18:02
  • 1
    @ MestreLion - Not necessarily: I'm processing thousands of files during a six-hour overnight run. If one of the files causes an exception, I want the trace so I can debug next day, but I want the processing to continue for the rest of the files. – Pierre Sep 14 '14 at 13:24
  • @Pierre: But the way this is written, it won't do that—it will print the exception, then exit with no error code. That's almost the exact opposite of what you want. – abarnert Sep 28 '14 at 02:13
  • As far as i can see this solution **still** gives traceback in case of failure, doesn't it? The OP wanted to exit **without traceback**. – agcala Feb 04 '20 at 12:24
  • Doesn't answer the question asked. – gerardw Apr 14 '21 at 11:29
83

Perhaps you're trying to catch all exceptions and this is catching the SystemExit exception raised by sys.exit()?

import sys

try:
    sys.exit(1) # Or something that calls sys.exit()
except SystemExit as e:
    sys.exit(e)
except:
    # Cleanup and reraise. This will print a backtrace.
    # (Insert your cleanup code here.)
    raise

In general, using except: without naming an exception is a bad idea. You'll catch all kinds of stuff you don't want to catch -- like SystemExit -- and it can also mask your own programming errors. My example above is silly, unless you're doing something in terms of cleanup. You could replace it with:

import sys
sys.exit(1) # Or something that calls sys.exit().

If you need to exit without raising SystemExit:

import os
os._exit(1)

I do this, in code that runs under unittest and calls fork(). Unittest gets when the forked process raises SystemExit. This is definitely a corner case!

Martijn Pieters
  • 889,049
  • 245
  • 3,507
  • 2,997
bstpierre
  • 26,946
  • 14
  • 63
  • 100
  • 4
    -1: This code is silly: why catch `SystemExit` just to call `sys.exit(e)`? Removing both lines has the *same* effect. Also, cleanup belongs to `finally:`, not `except Exception: ... raise`. – MestreLion Dec 05 '12 at 11:46
  • @MestreLion: You're free to downvote, but if you read my comment just above yours, that's only true for 2.5+. If you read all of my post, I explicitly said that the code is silly and suggested exactly what you said in your comment. – bstpierre Dec 05 '12 at 15:52
  • 2
    Sorry, you're right... I forgot there was a major re-structure of exceptions in Python 2.5. I tried to undo the downvote, but SO only allows me to do so if the answer is edited. So, since we are in 2012 and Python 2.4 is ancient history, why not edit it and show the correct (current) code upfront, leaving the pre-2.5 method as a footnote? It will improve the answer a lot and I'll be able to undo the downvote, and will gladly do so. Win-win for everyone :) – MestreLion Dec 07 '12 at 02:40
  • @MestreLion: I started editing as you suggested, but this answer really only makes sense in the context of the question and a 2.4 environment. The downvote doesn't upset me. – bstpierre Dec 07 '12 at 04:02
47
import sys
sys.exit(1)
Wojciech Bederski
  • 3,685
  • 1
  • 23
  • 28
13

The following code will not raise an exception and will exit without a traceback:

import os
os._exit(1)

See this question and related answers for more details. Surprised why all other answers are so overcomplicated.

IlliakaillI
  • 1,242
  • 11
  • 22
9

something like import sys; sys.exit(0) ?

rob
  • 33,487
  • 2
  • 52
  • 61
  • @mestreLion Then why do I get Dets 06 18:53:17 Traceback (most recent call last): File "debug_new.py", line 4, in import sys; sys.exit(0) SystemExit: 0 at org.python.core.PyException.fillInStackTrace(PyException.java:70) in my console? – Val Dec 06 '12 at 16:55
  • 3
    @Val: because you're not using a standard python console. Jython is not Python, and it looks like it (or at least its console) handles exceptions differently. – MestreLion Dec 07 '12 at 02:33
  • @Val See [*Why is sys.exit() causing a traceback?*](https://stackoverflow.com/q/48571212/3357935) – Stevoisiak Feb 02 '18 at 15:03
4

It's much better practise to avoid using sys.exit() and instead raise/handle exceptions to allow the program to finish cleanly. If you want to turn off traceback, simply use:

sys.trackbacklimit=0

You can set this at the top of your script to squash all traceback output, but I prefer to use it more sparingly, for example "known errors" where I want the output to be clean, e.g. in the file foo.py:

import sys
from subprocess import *

try:
  check_call([ 'uptime', '--help' ])
except CalledProcessError:
  sys.tracebacklimit=0
  print "Process failed"
  raise

print "This message should never follow an error."

If CalledProcessError is caught, the output will look like this:

[me@test01 dev]$ ./foo.py
usage: uptime [-V]
    -V    display version
Process failed
subprocess.CalledProcessError: Command '['uptime', '--help']' returned non-zero exit status 1

If any other error occurs, we still get the full traceback output.

RCross
  • 4,399
  • 3
  • 35
  • 39
  • 1
    For using `sys.trackbacklimit` in Python 3, see [this answer](http://stackoverflow.com/a/21556806/832230). – Acumenus Oct 06 '16 at 22:35
4

Use the built-in python function quit() and that's it. No need to import any library. I'm using python 3.4

2

I would do it this way:

import sys

def do_my_stuff():
    pass

if __name__ == "__main__":
    try:
        do_my_stuff()
    except SystemExit, e:
        print(e)
Karl W.
  • 21
  • 1
0

What about

import sys
....
....
....
sys.exit("I am getting the heck out of here!")

No traceback and somehow more explicit.

agcala
  • 1,273
  • 14
  • 25
-9
# Pygame Example  

import pygame, sys  
from pygame.locals import *

pygame.init()  
DISPLAYSURF = pygame.display.set_mode((400, 300))  
pygame.display.set_caption('IBM Emulator')

BLACK = (0, 0, 0)  
GREEN = (0, 255, 0)

fontObj = pygame.font.Font('freesansbold.ttf', 32)  
textSurfaceObj = fontObj.render('IBM PC Emulator', True, GREEN,BLACK)  
textRectObj = textSurfaceObj.get_rect()  
textRectObj = (10, 10)

try:  
    while True: # main loop  
        DISPLAYSURF.fill(BLACK)  
        DISPLAYSURF.blit(textSurfaceObj, textRectObj)  
        for event in pygame.event.get():  
            if event.type == QUIT:  
                pygame.quit()  
                sys.exit()  
        pygame.display.update()  
except SystemExit:  
    pass
  • 7
    If you would comment the code, it would increase the quality of the answer. –  Jun 23 '14 at 23:44