Exception wie abfangen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Amelie.

    Exception wie abfangen

    Moin moin

    Ich bin gerade etwas am bearbeiten und suche nun Möglichkeiten wie ich dies ersetzen kann.

    VB.NET-Quellcode

    1. Try
    2. Catch ex As Exception
    3. End Try


    Das ganze Try/Catch ist ja nun nicht so toll, wie man immer liest. Hab nun lange damit verbracht irgendwie Antworten zu erhalten.
    Frage: Wie kann ich an die Exception kommen ohne den Try / Catch Block um bei etwaigen unvorhersehbaren Fehlern eine Meldung ( Text, MSGBox oder wie auch immer ) auszugeben?

    Es gibt ja diese "Hauptklasse" der Exception???
    Vielleicht denke ich auch wieder in eine Falsche Richtung? :?:


    Ich habe mir eine Klasse geschrieben, welche mir die EX aus dem Catch in ein File schreibt. Soweit OK nun ich muss halt immer den TC-Block bauen. :(

    Mein kleines Test-Programm wo meine Klasse als dll eingebunden ist.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports EERecorder
    2. Public Class Form1
    3. Private WithEvents logger As New EventExceptionRecorder.eerHandler()
    4. Public Sub New()
    5. InitializeComponent()
    6. ' Setze das LogFormat
    7. logger.SetLogFormat(EventExceptionRecorder.LogFormat.txt)
    8. ' Setze das Mindest-Log-Level
    9. logger.MinLogLevel = EventExceptionRecorder.LogLevel.Info
    10. ' Event verarbeiten
    11. AddHandler logger.LogAdded, AddressOf HandleLogAdded
    12. ' Testausgaben
    13. Console.WriteLine("Das LogFormat steht auf: " & logger.LogFormat.ToString)
    14. Console.WriteLine("Der Mindest-logLevel steht bei: " & logger.MinLogLevel.ToString)
    15. End Sub
    16. Private Sub HandleLogAdded(ByVal logEntry As String, ByVal category As String)
    17. ' Vergleiche den LogLevel & setze ab welchem LogLevel MSG-Boxen etc. kommen
    18. Dim logLevelCategory As EventExceptionRecorder.LogLevel
    19. If [Enum].TryParse(category, logLevelCategory) AndAlso logLevelCategory >= EventExceptionRecorder.LogLevel.Success Then
    20. Dim LogMessage As String = "Neuer Log-Eintrag:" & String.Format("{0}", Environment.NewLine & String.Format("{0}", logEntry))
    21. MessageBox.Show(LogMessage, "Meldung vom EE-Recorder", MessageBoxButtons.OK, MessageBoxIcon.Information)
    22. End If
    23. End Sub
    24. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    25. ' Testausgaben
    26. lblLogLevel.Text = logger.MinLogLevel.ToString
    27. lblLogFormat.Text = logger.LogFormat.ToString
    28. ' Eine Debug Meldung produzieren
    29. logger.AddLogEntry(EventExceptionRecorder.LogLevel.Debug, "Das LogFormat steht auf: " & logger.LogFormat.ToString)
    30. ' Eine Erfolg Meldung mit eigener Message produzieren
    31. logger.AddLogEntry(EventExceptionRecorder.LogLevel.Success, "Eine Erfolgsmeldung ")
    32. ' Eine Exception produzieren
    33. Try
    34. Dim X As Integer = 2
    35. Dim Y As Integer = 0
    36. Dim Z As Integer = CInt(X / Y)
    37. Console.WriteLine(Z)
    38. Catch ex As Exception
    39. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Message)
    40. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Source)
    41. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.StackTrace)
    42. End Try
    43. End Sub
    44. End Class

    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    Ich denke, damit wirst du leben müssen. Ohne den Try/Catch wird deine App im Fehlerfall abschmieren. Richtige herangehensweise: Sicheren Code schreiben, Try/Catch nur wenns nicht anders geht. Meist kann man Exceptions vermeiden, dafür haben wir "If/Else/Else If". Man muss ja nicht nur bei Exceptions loggen, man kann durchaus auch in einer Bedingung(IF) was ins Log schreiben und abbrechen.

    VB.NET-Quellcode

    1. if not condition then
    2. Logger.Write("bedingung trifft unerwartet nicht zu: hierundda... diesunddas... bli, bla, blupp")
    3. return
    4. end if

    Zitat von mir 2023:
    Was interessiert mich Rechtschreibung? Der Compiler wird meckern wenn nötig :D

    Amelie schrieb:

    Das ganze Try/Catch ist ja nun nicht so toll, wie man immer liest.
    Nur nochmal zur Klarstellung: Es sollte nur dort verwendet werden, wo Fehler auftreten können, die man nicht durch andere Vorabprüfungen abfangen kann, siehe: Fange nur Exceptions ab, die Du kennst und sinnvoll bearbeiten kannst.

    Es gibt ja für VB-Programme den UnhandledExceptionHandler, aktivierbar unter Projekteigenschaften -> |Anwendung| -> [Anwendungsereignisse anzeigen] -> in der oberen, mittleren ComboBox dann (MyApplication Ereignisse) auswählen und in der rechten ComboBox das Event UnhandledException.


    Der fängt alles ab, was nicht durch Try-Catch abgefangen wurde.
    Ich habe mir für meine Programme eine Alternative gebaut, weil ich da was eigenes wollte. Dazu musst Du zu Programmbeginn folgendes einbauen:

    VB.NET-Quellcode

    1. AddHandler Application.ThreadException, AddressOf ExceptionHandlerFürFehlerDieInAnderenThreadsAuftauchen
    2. AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf ExceptionHandlerFürFehlerDieSonstNichtAbgefangenWurden

    Nun kann ich meine eigene Fehlerverarbeitung da dranhängen.
    Bilder
    • UnhandledExceptionEventHandler.png

      16,42 kB, 1.230×140, 59 mal angesehen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „VaporiZed“ ()

    @DTF

    Ich hatte das ähnlich auch schon mal versucht:

    VB.NET-Quellcode

    1. Try
    2. Dim X As Integer = 2
    3. Dim Y As Integer = 0
    4. Dim Z As Integer = CInt(X / Y)
    5. Debug.WriteLine(Z)
    6. Finally
    7. Dim ex As New Exception("Ein Fehler")
    8. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Message)
    9. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Source)
    10. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.StackTrace)
    11. End Try


    Das funktioniert im Editor recht gut aber wenn ich die "exe" laufen lasse kracht es hier natürlich.


    EDIT:13:05

    @VaporiZed
    Genau das UnhandledExceptionHandlerhatte ich auch gefunden und versucht einzubauen. Leider bekam ich immer die Meldung irgendwas mit Threadübergreifend... hab das leider schon wieder gelöscht.
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Amelie“ ()

    Das Logging gehört ja auch nicht in den Finally-Teil, sondern in den Catch-Teil.
    Finally wird aufgerufen, egal, ob ne Exception entsteht oder nicht, also auch, wenn alles gut gegangen ist.
    Wenn Du keinen Catch-Teil hast, kommt es zum geplanten Crash.

    @Amelie: Threadübergreifend? Bitte genauen Wortlaut. Denn Threadübergreifend heißt normalerweise für mich: schreibender Zugriff auf GUI-Teile von einem Nebenthread aus.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed
    Das mit dem Finaly , war mir bewusst, das dass IMMER ausgefürht wird. War nur so eine erste Idee die ich hatte. :)

    Habe das mit dem UnhandledException nochmal eingebaut. Hatte es aber in meiner anderen Version am Ende der Sub New stehen also nach InitializeComponent().
    Nach dem Test der kompilierten exe vom Testprogramm:


    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports EERecorder
    2. Public Class Form1
    3. Private WithEvents logger As New EventExceptionRecorder.eerHandler()
    4. Private ex As New Exception
    5. Public Sub New()
    6. AddHandler Application.ThreadException, AddressOf ExceptionHandlerForErrors
    7. AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf ExceptionHandlerForErrors
    8. InitializeComponent()
    9. ' Setze das LogFormat ( txt oder xml )
    10. logger.SetLogFormat(EventExceptionRecorder.LogFormat.xml)
    11. ' Setze das Mindest-Log-Level
    12. logger.MinLogLevel = EventExceptionRecorder.LogLevel.Info
    13. ' Event verarbeiten
    14. AddHandler logger.LogAdded, AddressOf HandleLogAdded
    15. ' Testausgaben
    16. Console.WriteLine("Das LogFormat steht auf: " & logger.LogFormat.ToString)
    17. Console.WriteLine("Der Mindest-logLevel steht bei: " & logger.MinLogLevel.ToString)
    18. End Sub
    19. Private Sub ExceptionHandlerForErrors(sender As Object, e As System.Threading.ThreadExceptionEventArgs)
    20. Dim ex As Exception = e.Exception
    21. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Message)
    22. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Source)
    23. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.StackTrace)
    24. End Sub
    25. Private Sub ExceptionHandlerForErrors(sender As Object, e As System.UnhandledExceptionEventArgs)
    26. Dim ex As Exception = DirectCast(e.ExceptionObject, Exception)
    27. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Message)
    28. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.Source)
    29. logger.LogException(ex, EventExceptionRecorder.ExceptionDetail.StackTrace)
    30. End Sub
    31. Private Sub HandleLogAdded(ByVal logEntry As String, ByVal category As String)
    32. ' Vergleiche den LogLevel & setze ab welchem LogLevel MSG-Boxen etc. kommen
    33. Dim logLevelCategory As EventExceptionRecorder.LogLevel
    34. If [Enum].TryParse(category, logLevelCategory) AndAlso logLevelCategory >= EventExceptionRecorder.LogLevel.Success Then
    35. Dim LogMessage As String = "Neuer Log-Eintrag:" & String.Format("{0}", Environment.NewLine & String.Format("{0}", logEntry))
    36. MessageBox.Show(LogMessage, "Meldung vom EE-Recorder", MessageBoxButtons.OK, MessageBoxIcon.Information)
    37. End If
    38. End Sub
    39. Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    40. ' Testausgaben
    41. lblLogLevel.Text = logger.MinLogLevel.ToString
    42. lblLogFormat.Text = logger.LogFormat.ToString
    43. ' Eine Debug Meldung produzieren
    44. logger.AddLogEntry(EventExceptionRecorder.LogLevel.Debug, "Das LogFormat steht auf: " & logger.LogFormat.ToString)
    45. ' Eine Erfolg Meldung mit eigener Message produzieren
    46. logger.AddLogEntry(EventExceptionRecorder.LogLevel.Success, "Eine Erfolgsmeldung ")
    47. ' Eine Exception produzieren
    48. Dim X As Integer = 2
    49. Dim Y As Integer = 0
    50. Dim Z As Integer = CInt(X / Y)
    51. Console.WriteLine(Z)
    52. End Sub
    53. End Class



    Das xml-File welches meine Class schreibt.
    Spoiler anzeigen

    XML-Quellcode

    1. <?xml version="1.0" encoding="utf-8"?>
    2. <LogEntries>
    3. <LogEntryItem>
    4. <Category>Success</Category>
    5. <Timestamp>25.09.2023 - 13:18</Timestamp>
    6. <Message>Eine Erfolgsmeldung </Message>
    7. </LogEntryItem>
    8. <LogEntryItem>
    9. <Category>Failure</Category>
    10. <Timestamp>25.09.2023 - 13:18</Timestamp>
    11. <Message>Die arithmetische Operation hat einen Überlauf verursacht.</Message>
    12. </LogEntryItem>
    13. <LogEntryItem>
    14. <Category>Failure</Category>
    15. <Timestamp>25.09.2023 - 13:18</Timestamp>
    16. <Message>TestNewERR</Message>
    17. </LogEntryItem>
    18. <LogEntryItem>
    19. <Category>Failure</Category>
    20. <Timestamp>25.09.2023 - 13:18</Timestamp>
    21. <Message> bei TestNewERR.Form1.Form1_Load(Object sender, EventArgs e) in A:\TestUmgebung\TestNewEER\TestNewERR\Form1.vb:Zeile 66.
    22. bei System.EventHandler.Invoke(Object sender, EventArgs e)
    23. bei System.Windows.Forms.Form.OnLoad(EventArgs e)
    24. bei System.Windows.Forms.Form.OnCreateControl()
    25. bei System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
    26. bei System.Windows.Forms.Control.CreateControl()
    27. bei System.Windows.Forms.Control.WmShowWindow(Message&amp; m)
    28. bei System.Windows.Forms.Control.WndProc(Message&amp; m)
    29. bei System.Windows.Forms.ScrollableControl.WndProc(Message&amp; m)
    30. bei System.Windows.Forms.Form.WmShowWindow(Message&amp; m)
    31. bei System.Windows.Forms.Form.WndProc(Message&amp; m)
    32. bei System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message&amp; m)
    33. bei System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message&amp; m)
    34. bei System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)</Message>
    35. </LogEntryItem>
    36. </LogEntries>
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „Amelie“ ()

    @Fakiz

    Die DebugAusgaben werden im Releas eh nicht ausgegeben.

    ​der Program Klasse abonnieren, falls es bei VB soetwas
    Was meinst du damit? Verstehe ich nicht. ;(
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh:
    @Amelie Dies:
    Projekt => Eigenschaften => Anwendung => Anwendungsereignisse anzeigen
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Was ja schon genauso in Post#3 steht :S
    Da aber bei der Standardprojekteinstellung Schließen, wenn das Startformular geschlossen wird das MainForm immer existient bis zum Ende ist, kann man (m.E.) auch auf die ebenfalls in Post#3 erwähnte und daraufhin in Post#6 umgesetzte Variante bauen.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @VaporiZed

    Das Bild was in deinem Post#3 ist, habe ich gestern gar nicht gesehen!

    Aber das mit dem ​UnhandledException funktioniert jetzt soweit wie mein letzer Code hier ist. ;)
    Asperger Autistin. Brauche immer etwas um gewisse Sachen zu verstehen. :huh: