2016-07-26 22 views
1

Ich möchte raise verwenden, ohne das Traceback auf dem Bildschirm zu drucken. Ich weiß, wie man das mit try ..catch tut, findet aber keinen Weg mit raise. HierFehler ohne Rückverfolgung auslösen

ein Beispiel:

def my_function(self): 
    resp = self.resp 
    if resp.status_code == 404: 
     raise NoSuchElementError('GET'+self.url+'{}'.format(resp.status_code)) 
    elif resp.status_code == 500: 
     raise ServerErrorError('GET'+self.url+'{}'.format(resp.status_code)) 

Wenn diese Ausführung, wenn ich einen 404 haben, die Zurückverfolgungs auf dem Bildschirm gedruckt wird.

Traceback (most recent call last): 
    File "test.py", line 32, in <module> 
    print ins.my_function() 
    File "api.py", line 820, in my_function 
    raise NoSuchElementError('GET ' + self.url + ' {} '.format(resp.status_code)) 

Dies ist ein Wrapper-API und ich will nicht Benutzer die Zurückverfolgungs sehen, aber die API-Antwortcodes und Fehlermeldungen statt zu sehen.

Gibt es eine Möglichkeit, es zu tun?

+0

Display-Formatierung ist nicht 'raise''s Job. Wenn Sie steuern möchten, wie das Programm auf diese Ausnahmen reagiert, fangen Sie sie auf einer höheren Ebene in der Struktur Ihres Programms ab und tun Sie, was Sie damit machen. – user2357112

Antwort

2

Das Problem besteht nicht darin, irgendetwas zu erhöhen, sondern mit dem, was der Python-Interpreter tut, wenn Ihr Programm mit einer Ausnahme endet (und es einfach den Stack-Trace ausgibt). Was sollten Sie tun, wenn Sie es vermeiden wollen, versuchen zu setzen ist außer Block um alles, was Sie wollen „verstecken“ der Stack-Trace, wie:

def main(): 
    try: 
    actual_code() 
    except Exception as e: 
    print(e) 

Der andere Weg, um die exeption Handler zu ändern ist, sys.excepthook(type, value, traceback), Ihre eigene Logik zu tun, wie

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

import sys 
sys.excepthook = my_exchandler 

Sie können sogar Bedingung der Ausnahme type und machen die besondere Logik iff es Ihre Art von Ausnahme ist, und ansonsten - Backoff mit dem Original.

1

Fangen Sie die Ausnahme ab, melden Sie sie und geben Sie etwas zurück, das anzeigt, dass etwas schief gelaufen ist (das Senden einer 200 zurück, wenn eine Abfrage fehlgeschlagen ist, wird wahrscheinlich Probleme für Ihren Client verursachen).

try: 
    return do_something() 
except NoSuchElementError as e: 
    logger.error(e) 
    return error_response() 

Die gefälschte error_response() Funktion alles tun, könnte eine leere Antwort oder eine Fehlermeldung Form zurückkehrt. Sie sollten immer noch die richtigen HTTP-Statuscodes verwenden. Es klingt, als ob Sie in diesem Fall einen 404 zurückgeben sollten.

Sie sollten Ausnahmen ordnungsgemäß behandeln, aber Sie sollten Fehler von Clients nicht vollständig ausblenden. Im Falle Ihrer NoSuchElementError Ausnahme klingt es wie der Client informiert werden sollte (der Fehler könnte an ihrem Ende sein).

1

Ich stieß auf ein ähnliches Problem, wo eine Elternklasse den Ausnahmewert auf raise verwendete, um Nachrichten weiterzuleiten, aber wo ich das Traceback nicht ablegen wollte. @lejlot bietet eine großartige Lösung mit sys.excepthook, aber ich musste es mit einem eingeschränkteren Anwendungsbereich anwenden. Hier ist die Änderung:

import sys 
from contextlib import contextmanager 

@contextmanager 
def except_handler(exc_handler): 
    "Sets a custom exception handler for the scope of a 'with' block." 
    sys.excepthook = exc_handler 
    yield 
    sys.excepthook = sys.__excepthook__ 

Dann, es zu benutzen:

def my_exchandler(type, value, traceback): 
    print(': '.join([str(type.__name__), str(value)])) 

with except_handler(my_exchandler): 
    raise Exception('Exceptional!') 

# -> Exception: Exceptional! 

diese Weise, wenn eine Ausnahme nicht in dem Block angehoben wird, Standardausnahmebehandlung für alle nachfolgenden Ausnahmen wieder aufnehmen wird:

with except_handler(my_exchandler): 
    pass 

raise Exception('Ordinary...') 

# -> Traceback (most recent call last): 
# -> File "raise_and_suppress_traceback.py", line 22, in <module> 
# ->  raise Exception('Ordinary...') 
# -> Exception: Ordinary...