Ich schreibe ein Modul und möchte eine einheitliche Ausnahmehierarchie für die Ausnahmen haben, die es auslösen kann (z. B. Erben von einer FooError
abstrakten Klasse für alle foo
spezifischen Ausnahmen des Moduls). Auf diese Weise können Benutzer des Moduls diese bestimmten Ausnahmen abfangen und bei Bedarf eindeutig behandeln. Viele der vom Modul ausgelösten Ausnahmen werden jedoch aufgrund einer anderen Ausnahme ausgelöst. z. B. Fehler bei einer Aufgabe aufgrund eines OSError in einer Datei.
Was ich brauche, ist, die gefangene Ausnahme so zu "verpacken", dass sie einen anderen Typ und eine andere Nachricht hat , so dass Informationen weiter oben in der Propagierungshierarchie verfügbar sind, je nachdem, was die Ausnahme abfängt. Aber ich möchte den vorhandenen Typ, die Nachricht und den Stack-Trace nicht verlieren. Das sind alles nützliche Informationen für jemanden, der versucht, das Problem zu beheben. Ein Ausnahmebehandler der obersten Ebene ist nicht gut, da ich versuche, die Ausnahme zu dekorieren, bevor sie den Propagierungsstapel weiter nach oben führt, und der Handler der obersten Ebene zu spät ist.
Dies wird teilweise dadurch gelöst, dass die foo
spezifischen Ausnahmetypen meines Moduls vom vorhandenen Typ abgeleitet werden (z. B. class FooPermissionError(OSError, FooError)
). Dies macht es jedoch nicht einfacher, die vorhandene Ausnahmeinstanz in einen neuen Typ zu packen oder die Nachricht zu ändern.
In Pythons PEP 3134 „Ausnahmekettung und eingebettete Tracebacks“ wird eine in Python 3.0 akzeptierte Änderung für die Verkettung von Ausnahmeobjekten erläutert, um anzuzeigen, dass während der Behandlung einer vorhandenen Ausnahme eine neue Ausnahme ausgelöst wurde.
Was ich versuche zu tun, ist verwandt: Ich brauche es auch in früheren Python-Versionen, und ich brauche es nicht zum Verketten, sondern nur für Polymorphismus. Was ist der richtige Weg, um dies zu tun?
except Exception as e
-> raise type(e), type(e)(e.message + custom_message), sys.exc_info()[2]
-> Diese Lösung stammt aus einer anderen SO-Frage . Das ist nicht schön, aber funktional.