Fehlerhandling und Übersetzung
-
Hallo zusammen,
ich möchte meinen Horizont beim Thema Fehlerhandling und Übersetzungen im Bezug auf Exceptions erweitern.
Auf der Arbeit ist folgende Situation:
Wir haben kein „modernes“ Fehlerhandlingsystem. Übersetzungen werden über Makros/Defines gelöst. Für jede Fehlerklasse, die von einer Basisklasse abgeleitet ist, existieren #define-Konstanten für Fehlercodes sowie (falls nötig) eine eigene Übersetzungs-ID.Was ich privat lernen/umsetzen möchte:
Ich schreibe privat kleine Projekte und möchte dort ein gutes, zeitgemäßes Fehlerhandling etablieren – idealerweise so, dass es sowohl für Logging als auch für Benutzertexte geeignet ist. Ich möchte auch mir eigene kleine Libs schreiben und dort möchte ich dann ein gutes Fehlerhandling System implementieren.Beispiel:
Angenommen es gibt eine Domänenklasse Order. Der Konstruktor wirft bei ungültigen Parametern std::invalid_argument.class Order { public: Order(std::string id, int quantity) { if (id.empty()) { throw std::invalid_argument("Order id must not be empty"); } if (quantity <= 0) { throw std::invalid_argument("Quantity must be positive"); } // ... } };
Fragen:
- Sprache der Exception-Message:
Sollte die Nachricht in Exceptions standardmäßig Englisch/deutsch sein (neutral für uns Entwickler oder das Logging), oder sollte sie lokalisiert sein (z. B. Deutsch/Englisch/Spanisch je nach Umgebung)?
Mein Gedanke: Die Klasse könnte tief im Code oder nahe an der UI verwendet werden. An der UI ist Lokalisierung sinnvoll; tief im Code evtl. eher neutrale/englische Texte fürs Logging oder für die Entwicklung. - Mehrere mögliche Fehlerquellen in einem try/catch:
Wenn in einem Block mehrere Objekte std::invalid_argument werfen könnten:
Fangt ihr eher basistypisch catch (const std::exception& ex) und mappt dann zentral anhand von Fehlercodes?
Oder nutzt ihr für die Domäne eigene Exceptiontypen (z. B. OrderError, CustomerError), um präziser unterscheiden zu können? - Im Domain-Driven Design gäbe es ggf. eine UI Order Klasse, die den Auftrag in der UI darstellt. Wäre dann diese für das Mapping in die richtige Lokalisierung zuständig und nicht die normale Domain Klasse?
- Trennt ihr Log-Text (stabil, englisch, mit technischen Details) von Benutzertext (lokalisiert, freundlich, kontextualisiert)? Wenn ja: Wie sorgt ihr dafür, dass beide Pfade konsistent bleiben?
Ich habe hier im Forums dazu nichts gefunden.
- Sprache der Exception-Message:
-
Hallo @KK27,
einleitend möchte ich erwähnen, dass meiner Meinung nach, Exceptions nur bei nicht behebbaren Fehlern, die den normalen Programmablauf unmöglich machen, geworfen werden sollten.-
Zu 1.: Kommt doch ganz auf die Entwicklersprache an. In der Regel können Entwickler englisch, also Exception Texte in englisch. Ich habe aber auch mal in einem Team (Behörde) gearbeitet, wo deutsch als Sprache vorgeschrieben war. Also die Klassennamen, Attribute und Methoden in deutsch geschrieben wurden. Da wurden auch die Fehlertexte in deutsch geschrieben.
Fehlertexte für den Anwender würde ich lokalisieren, also nicht direkt std::exception::what ausgeben, welches ja in der "Entwicklersprache" geschrieben sein sollte. -
Zu 2.: Wenn in meinem Code eine Exception gefangen wird, dann Exception-Typ abhängig, also mehrere "catch" Blöcke.
Ich persönlich arbeite mit einer abgeleiteten Exception mit einer Fehlernummer zur weiteren Auswertung und dem Dateinamen mit Zeilennummer wo diese geworfen wird. ::what ist also grundsätzlich nicht für den späteren Anwender, sondern nur für Entwickler gedacht.
Da wo die Exception gefangen wird, und es ist die abgeleitete Exception, wird für den weiteren Ablauf die Fehlernummer ausgewertet. Die Fehlernummer und der Dateinamen mit Zeilennummer wird ggf. bis an den Anwender weitergereicht um diese Informationen für ein ggf. nötiges Fehlerticket an die Entwickler weitergeben zu können. Alles was der Anwender an Fehlermeldungstexten sieht, ist aber lokalisiert. -
Zu 3.: Ich vermute, dass Du mit UI-Klasse eine Oberflächenklasse meinst, die eine entsprechende technische Klasse irgendwie referenziert und UI spezifische Funktionalität wie z.B. Wandlung von UI Typen in Domain-Typen und umgekehrt zuständig ist. Wenn Texte für den Anwender anfallen, dann mMn in der UI-Klasse lokalisiert.
-
Zu 4.: Wenn Log-Texte in Protokolldateien auch für den Anwender vorgesehen sind, wurden diese in meinen bisherigen Projekten grundsätzlich in der Entwicklersprache geschrieben. Grund war, das in meinen Projekten die GUI grundsätzlich auf eine Domain zugegriffen hat und die Domain nichts über die GUI weiß. Wenn also die Domain und die GUI-Klassen in die selbe Protokolldatei geschrieben haben, wurde nur eine Sprache genutzt.
Ich weiß jetzt natürlich nicht, ob dieses Dir weiterhilft.
-
-
@Helmut-Jakoby sagte in Fehlerhandling und Übersetzung:
Hallo @KK27,
einleitend möchte ich erwähnen, dass meiner Meinung nach, Exceptions nur bei nicht behebbaren Fehlern, die den normalen Programmablauf unmöglich machen, geworfen werden sollten.-
Zu 1.: Kommt doch ganz auf die Entwicklersprache an. In der Regel können Entwickler englisch, also Exception Texte in englisch. Ich habe aber auch mal in einem Team (Behörde) gearbeitet, wo deutsch als Sprache vorgeschrieben war. Also die Klassennamen, Attribute und Methoden in deutsch geschrieben wurden. Da wurden auch die Fehlertexte in deutsch geschrieben.
Fehlertexte für den Anwender würde ich lokalisieren, also nicht direkt std::exception::what ausgeben, welches ja in der "Entwicklersprache" geschrieben sein sollte. -
Zu 2.: Wenn in meinem Code eine Exception gefangen wird, dann Exception-Typ abhängig, also mehrere "catch" Blöcke.
Ich persönlich arbeite mit einer abgeleiteten Exception mit einer Fehlernummer zur weiteren Auswertung und dem Dateinamen mit Zeilennummer wo diese geworfen wird. ::what ist also grundsätzlich nicht für den späteren Anwender, sondern nur für Entwickler gedacht.
Da wo die Exception gefangen wird, und es ist die abgeleitete Exception, wird für den weiteren Ablauf die Fehlernummer ausgewertet. Die Fehlernummer und der Dateinamen mit Zeilennummer wird ggf. bis an den Anwender weitergereicht um diese Informationen für ein ggf. nötiges Fehlerticket an die Entwickler weitergeben zu können. Alles was der Anwender an Fehlermeldungstexten sieht, ist aber lokalisiert. -
Zu 3.: Ich vermute, dass Du mit UI-Klasse eine Oberflächenklasse meinst, die eine entsprechende technische Klasse irgendwie referenziert und UI spezifische Funktionalität wie z.B. Wandlung von UI Typen in Domain-Typen und umgekehrt zuständig ist. Wenn Texte für den Anwender anfallen, dann mMn in der UI-Klasse lokalisiert.
-
Zu 4.: Wenn Log-Texte in Protokolldateien auch für den Anwender vorgesehen sind, wurden diese in meinen bisherigen Projekten grundsätzlich in der Entwicklersprache geschrieben. Grund war, das in meinen Projekten die GUI grundsätzlich auf eine Domain zugegriffen hat und die Domain nichts über die GUI weiß. Wenn also die Domain und die GUI-Klassen in die selbe Protokolldatei geschrieben haben, wurde nur eine Sprache genutzt.
Ich weiß jetzt natürlich nicht, ob dieses Dir weiterhilft.
- Interessante Idee. Dadurch weißt man genau in welcher Source der Fehler auftaucht und man kann es einfacher lokalisieren. Merke ich mir.
Das hilft mir schon weiter. Dadurch habe ich einen Einblick, welche Möglichkeiten es alles gibt.
-
-
@Helmut-Jakoby Zeilennummern würde ich nicht mit ausgeben. Sobald sich was am Code ändert ist das veraltet und man denkt nicht dran, das nach zu ziehen.
-
Hallo @Schlangenmensch,
mach ich über "FILE" und "LINE", jeweils mit 2 führenden und folgenden Unterstrichen, wird hier nicht angezeigt. Sind vordefinierte Makros.
-
@Helmut-Jakoby Ok, die Makros hatte ich gerade tatsächlich nicht auf dem Schirm.
Aber, dann möchte ich hier auf
https://en.cppreference.com/w/cpp/utility/source_location.html
verweisen