Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > de.comp.lang.python > #5506
| From | Peter Otten <__peter__@web.de> |
|---|---|
| Newsgroups | de.comp.lang.python |
| Subject | Re: [Python-de] Exception erneut werfen (re-raise) |
| Date | 2019-06-23 15:24 +0200 |
| Organization | None |
| Message-ID | <mailman.5.1561296279.29664.python-de@python.org> (permalink) |
| References | <87blyo5zqn.fsf@x230.onfire.org> <7898859.zcJcWZ0syB@palindrom> |
Christian Barthel wrote:
> Ich habe einen Code-Auszug der eine HTTP Bibliothek (requests
> Modul) nutzt. Diese wirft unterschiedliche Exceptions die ich
> auffange. Ich würde aber gerne die Exception an dieser Stelle
> noch nicht fangen, sondern im Prinzip an den Aufrufer weitergeben
> damit ich dann alle Exceptions in der Hauptschleife zentral
> fangen kann und Loggen kann.
>
> Dies geht; allerdings verliere ich dann die Möglichkeit auf die
> lokalen Variablen der innersten Funktion (dort wo der Request
> erzeugt und konstruiert wird) zuzugreifen.
>
> Meine Idee im Moment wäre mittels "raise .. from.." eine neue
> Exception zu generieren und die zusätzlichen Parameter als
> Argumente mitzugeben. Illustrativ und vereinfacht würde das in
> etwa so aussehen:
>
> def foo():
> assert 0 == 1
>
> def bar():
> someVar = ..
> try:
> foo()
> except AssertionError as e:
> raise AssertionError('foo ' + str(foo)) from e
>
> Somit kann ein Aufrufer von bar() die Belegung von foo in einer
> Fehlermeldung einbauen und die Daten der Ursprünglichen Exception
> sind weiter vorhanden. Mich würde interessieren ob es eine
> Alternative oder einfachere Möglichkeit dazu geben würde und wie
> (erfahrenere) Python Programmierer das lösen würden?
foo in deinem Beispiel ist allerdings eine globale Variable.
Wenn es nur darum geht, lokale Variablen im Callstack zu inspizieren, kommst
du auch ohne erneutes try...except aus:
$ cat traceback_locals.py
import sys
def f(n):
if n: return f(n-1)
assert False
try:
f(3)
except:
etype, exc, tb = sys.exc_info()
while True:
tb = tb.tb_next
if tb is None:
break
print(tb.tb_frame.f_locals)
$ python3 traceback_locals.py
{'n': 3}
{'n': 2}
{'n': 1}
{'n': 0}
Das ist nur zur Demonstration, Editoren/IDEs mit Python-Support sollten den
Zugriff auf den Callstack bieten, ohne dass du eine Zeile extra schreiben
musst.
Oft will man allerdings gezielt zusätzliche Informationen übermitteln oder
Lowlevel-Exceptions in anwendungsspezifische Ausnahmen "übersetzen". Dann
ist dein Vorgehen das Mittel der Wahl. Ich ziehe jedoch unbearbeitete
Werte vor, die man bei Bedarf nicht mühsam aus einem String herausoperieren
muss, also in etwa
class MyAssertionError(AssertionError):
def __init__(self, message, foo=None):
super().__init__(message, foo)
self.foo = foo
Back to de.comp.lang.python | Previous | Next — Previous in thread | Next in thread | Find similar
Exception erneut werfen (re-raise) Christian Barthel <bch@online.de> - 2019-06-23 13:04 +0200
Re: [Python-de] Exception erneut werfen (re-raise) Peter Otten <__peter__@web.de> - 2019-06-23 15:24 +0200
Re: [Python-de] Exception erneut werfen (re-raise) Christian Barthel <bch@online.de> - 2019-06-23 17:42 +0200
csiph-web