Laden...

Neben "false" auch die Exception-Message zurückgeben - Methode mit mehreren Rückgabewerten

Erstellt von Gogeta vor 7 Jahren Letzter Beitrag vor 7 Jahren 2.703 Views
G
Gogeta Themenstarter:in
152 Beiträge seit 2012
vor 7 Jahren
Neben "false" auch die Exception-Message zurückgeben - Methode mit mehreren Rückgabewerten

Hallo,

ich habe eine DLL programmiert und diese wird auch in einer Anwendung (nicht C#) verwendet.

Ich habe einige Methoden diese haben den Rückgabewert Boolean. In der Methode habe ich ein try-catch block. Sollte die Methode richtig ausgeführt werden so bekommen wir ein true wieder gegeben... sollte die Methode in einen fehler laufen (catch) so bekommen wir ein false.

nun möchte ich aber das wenn ein false wieder geben wird, dass auch die Fehlermeldung (Exception.Message) wiedergegeben wird!?
Mit zwei Methoden mit dem selben Namen aber unterschiedlichen Rückgabewert geht nicht!

Ist es überhaupt möglich sowas zu realisieren ?

--> Also in C# in meiner Umgebung habe ich dafür eine Klasse mit zwei variablen (get und set) und habe dann meine Methode in diesen typen umgewandelt und anschließend habe ich das bekommen wie ich es wollte aber ich musste in c# dafür die klasse die ich selber erstellt habe, auch deklarieren das kann ich in der Anwendung von dritten nicht !

3.003 Beiträge seit 2006
vor 7 Jahren

Möglichkeiten:

-"out"-Parameter


public Exception TrySomething(out bool result);
//oder
public bool TrySomething(out Exception ex);

  • Rückgabeobjekt

interface IOperationResult 
{
    bool Result { get; }
    Exception Exception { get; }
    bool HasException { get; }
}

public IOperationResult DoSomething();

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

G
Gogeta Themenstarter:in
152 Beiträge seit 2012
vor 7 Jahren

Halo LaTimo,

danke für deine schnelle Antwort.
Das mit dem out-Parameter sieht nicht so aufwändig aus (müsste nämlich über 40 Methoden anpassen).

Doch wie setzte ich diesen out Parameter in meiner Methode ein !?

public bool UpdateIncident(string nummer, string nachricht)
        {
            bool re_Bool = false;
            try
            {
                Incident incident= new Incident();
                incident.Id = nummer;
                incident.Pics = nachricht;
                service.update(incident);
                re_Bool = true;
            }
            catch (Exception)
            {
                re_Bool = false;
            }
            return re_Bool;
        }

Wenn Catch dann Exception auswerfen...

2.298 Beiträge seit 2010
vor 7 Jahren

Hallo,

ist eigentlich relatvi einfach:


public bool UpdateIncident(string nummer, string nachricht, out Exception exception)
{
    exception= null;
    // ...
   catch(Exception exc)
   {
        exception = exc;
   }   
}

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

T
708 Beiträge seit 2008
vor 7 Jahren

In den Projekten, wo ich DLL´s in einem nicht C#-Umfeld einsetze, habe ich meist ein Property "LastException" und "LastExceptionMessage", welche man auslesen kann.
Die LastException wird in jedem Catch-Block gefüllt. Die Message wrappt einfach nur den Nachrichtentext.
Hat sich so bewährt, da nicht alle Applikationen mit ref & out klar kommen und zum teil sogar nur die basis Objekttypen unterstützen.

5.299 Beiträge seit 2008
vor 7 Jahren

Tatsächlich ists imo ein FehlDesign, wenn man bei einem Fehler was anderes tut, als eine Exception zu werfen - und in einer Dll erst recht.

Das rächt sich nun.

Ich hab mal einen längeren Artikel dazu verzapft - im Grunde geht es nur um den einen einfachen - übrigens unbestrittenen - Grundsatz:
"Fange nur die Exceptions, die du auch behandeln kannst!".

Die Crux ist nämlich, das auch ernst zu nehmen.

https://www.vb-paradise.de/index.php/Thread/73363-TryCatch-ist-ein-heißes-Eisen/?postID=593077#post593077

Der frühe Apfel fängt den Wurm.

G
Gogeta Themenstarter:in
152 Beiträge seit 2012
vor 7 Jahren

Hallo inflames2k,

ich werde das sofort testen, also die DLL wird unter Delphi verwendet, ich denke das mit out sollte dort kein Problem sein oder!?

Hallo trib,

das hört sich gut an, sollte das mit out nicht funktionieren werde ich diese Lösung umsetzen.

Hallo ErfinderDesRades,

recht hast! ich bin jetzt auf die Nase gefallen und werde das natürlich in Zukunft anders lösen!

Danke für die Antworten.

LG

3.003 Beiträge seit 2006
vor 7 Jahren

Völlig richtig. Wenn du die Exception haben willst, dann wirf sie. Der Rest oben sind nur (mehr oder minder dreckige) Workarounds.

In diesem Fall würde ich darüber nachdenken, das try-catch in deiner dll-Methode rauszuwerfen.

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

G
Gogeta Themenstarter:in
152 Beiträge seit 2012
vor 7 Jahren

Hallo LaTimo,

sollte ich das wirklich tun?

Also ich habe jetzt meine Methode mit einem out-Parameter erweitert. In C# funktioniert das hervorragend. Doch in Delphi kann ich das so nicht benutzt -.-

Ich prüfe die Idee von trib...

LG

16.842 Beiträge seit 2008
vor 7 Jahren

Exceptions soweit durchreichen, bis sie wirklich sinnvoll abgefangen werden.
Out für die Weitergabe von Exceptions zu missbrauchen ist der falsche Weg. Fehler unterdrücken und nur sagen, dass etwas nicht geklappt hat aber nicht was gena: Fehldesign.

5.299 Beiträge seit 2008
vor 7 Jahren

Wenn man faul ist, kann man sich oft auch das "durchreichen" sparen:
Weil wenn zB iwo eine NullReferenceException auftritt - wieso die dann catchen, und Re-Throwen? (was anderes kann "durchreichen" ja nicht bedeuten)
Sie fliegt doch auch so, und wenn sie den Fehler genug genau bezeichnet, muss man nichtmal durchreichen, sondern kann sie einfach fliegen lassen.

Aber das hängt von der konkreten Implementation ab.

Der frühe Apfel fängt den Wurm.

3.003 Beiträge seit 2006
vor 7 Jahren

(was anderes kann "durchreichen" ja nicht bedeuten)

Doch, einfach nicht abfangen 😉. (Resharper schnauzt sowieso rum, wenn man im catch-Block nur ein throw; hat. rethrow nur, wenn man die Exception wegprotokolliert. Ansonsten eben durch den Stack schießen lassen (== weiterreichen), bis sich einer dafür interessiert.

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

16.842 Beiträge seit 2008
vor 7 Jahren
try (Exception e)
{
 throw;
}

noch fast vertretbar, verändert den Stacktrace nicht.
Erzeugt weder von LightBulb noch von ReSharper ein Warning.

try (Exception e)
{
 throw e;
}

ist schlecht, verändert den Stacktrace.
Erzeugt ein Warning.

Wird die Exception hier nicht verarbeitet: catch weglassen!

3.003 Beiträge seit 2006
vor 7 Jahren
try (Exception e)  
{  
 throw;  
}  

noch fast vertretbar, verändert den Stacktrace nicht.
Erzeugt weder von LightBulb noch von ReSharper ein Warning.

Von Re# schon.

Severity: Warning
Category: Redundancies in Code
Content: catch clause is redundant

LaTino

"Furlow, is it always about money?"
"Is there anything else? I mean, how much sex can you have?"
"Don't know. I haven't maxed out yet."
(Furlow & Crichton, Farscape)

16.842 Beiträge seit 2008
vor 7 Jahren

Dann hast Du Redundanzen aktiv in den Settings als Warning und nicht als Hint hinterlegt.
Der Optimierer dürfte es eh aus dem Code hauen.

T
2.224 Beiträge seit 2008
vor 7 Jahren

Würde hier grundsätzlich auch die Exception fliegen lassen.
Wenn deine Verarbeitung einen Fehler wirft und du ihn zwar fängst und auch durch out hoch reichst, ist auch nicht garantiert, dass jemand die Exception prüft, loggt oder verarbeitet.

Entsprechend macht es mehr Sinn, es knallen zu lassen.
Hier kann man intern noch ein try/catch einbauen um den Fehler loggen zu lassen.
Dann sollte man aber die Exception mit throw weiterwerfen.
Ansonsten kannst du eben nicht sicher sein, ob jemand den Fehler auch bemerkt.
Auf Annahmen, dass der Konsument deiner Funktionen sich dann tatsächlich kümmert, soll man sich nie verlassen.

Nachtrag:
Hatte übrigens erst vor zwei Wochen das gleiche dilema.
Ich hatte in einem Webservice die Exception gefangen und dann nur grob geloggt.
Die Liste, die ich dann als Ergebis liefern wollte, sollte eigentlich leer sein wurde aber schon halb befüllt.
Die Liste hatte dann einige Einträge, die gültig waren, hätte aber auch noch zusätzlich ungültig enthalten müssen.
Durch ein Timeout bei einem Webservice Aufruf, knallte es und wir mussten erst einmal prüfen warum trotz eines Fehlers das Ergebnis okay war.
Entsprechend sollte man nie stillschweigend Fehler fangen!
Kostet eine Menge Zeit solche fiesen Fehler zu suchen und zu beheben!

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.