Results 1 to 6 of 6

Thread: [RESOLVED] Calling API's: Automatic error throwing

  1. #1

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Resolved [RESOLVED] Calling API's: Automatic error throwing

    When calling API's or other external functions it is only possible to get thrown errors using "GetLastError". I made the following function for this:
    Code:
        Public Sub ThrowError()
            Dim ex As New System.ComponentModel.Win32Exception(Runtime.InteropServices.Marshal.GetLastWin32Error())
            If ex.NativeErrorCode <> 0 Then Throw ex
        End Sub
    I have two questions to "simplify" my code usage:

    1. How can I make the debugger point to where the "ThrowError" is called, instead of highlighting the "Throw ex" line. I can pass the location to this Function, but a Messagebox is not everything...

    2. How can I make the "ThrowError" check get called whenever an API is used? For example, duplicating all API's and adding the call to ThrowError in the end is kind of lengthy:
    Code:
        Private Class API
            Public Declare Function SetCursor Lib "user32" (ByVal hCursor As IntPtr) As IntPtr
        End Class
        Public Function SetCursor(ByVal hCursor As IntPtr) As IntPtr
            SetCursor = API.SetCursor(hCursor)
            ThrowError()
        End Function

  2. #2

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Calling API's: Automatic error throwing

    Bump.

    I guess "whenever an API gets called" is pretty much impossible without calling it in cloned functions. But what about the thrown error?

    I want it like this:
    Code:
    Public Sub Caller()
        CalledError() '<---- ERROR HIGHLIGHT HERE
    End Sub
    
    Public Sub CalledError()
        Throw New Exception("Error message")
    End Sub
    Many functions will eventually call this "error" function, and it is pretty useless to highlight the function that is called instead of WHERE it was called.
    I believe I have to change the stack trace, but absolutely no clue how to do this, since there is no stack trace...

    EDIT

    This is some sort of solution, but it would make the code 5x as long...
    Code:
    Public Sub Caller()
        Try
            CalledError()
        Catch ex As Exception
            Throw ex '<----- ERROR HIGHLIGHT HERE
        End Try
    End Sub

  3. #3
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: Calling API's: Automatic error throwing

    try

    Code:
    Imports System.Diagnostics
    Imports System.Runtime.CompilerServices
    Code:
      ' <MethodImpl(MethodImplOptions.NoInlining)> _
        Sub callerror()
            [error]()
        End Sub
    
        '  <MethodImpl(MethodImplOptions.NoInlining)> _
        Sub [error]()
            Dim frame As StackFrame = New StackFrame(1, False)
    
            MsgBox(frame.GetMethod.Name)
            Dim e As New Exception
    
    
        End Sub

  4. #4

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: Calling API's: Automatic error throwing

    This is kind of what I had previously, but without the "location passing" part. It would not break the code execution either, I am more looking for a way of telling the debugger that the error was not thrown from where the "throw" line is, but from the calling function.

    Any ways, I found one pretty awesome solution:
    I made a global error handler!
    Code:
        'Error handling
        Private Shared _lasterror As Exception
        Public Shared Function HasError() As Boolean
            If _lasterror IsNot Nothing Then Return True
            Return Marshal.GetLastWin32Error() <> 0
        End Function
        Public Shared Property LastError() As Exception
            Get
                If _lasterror Is Nothing Then
                    Return New System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error())
                Else
                    Return _lasterror
                End If
            End Get
            Set(ByVal value As Exception)
                _lasterror = value
            End Set
        End Property
    I can now do commands like these:
    Code:
    SendString("SEND sudsaidsaud", IntPtr.Zero)
    If HasError() Then Throw LastError
    Code:
    SendMessage(IntPtr.Zero, 0, 0, 0)
    If HasError() Then Throw LastError
    API.WM.SETFOCUS(5)
    If API.HasError Then Throw API.LastError
    And it puts me nicely at where it occured, and I can use an else to do code after the function (if needed). Plus, I can now throw from any location.

    I guess it is pretty hard to beat this, although it would be better to use some sort of "SetLastWin32Error" instead of adding another global variable.
    API's don't need to set anything, since they set the last win32 error any ways. For other functions, for example error code returning functions, I added the "_lasterror" variable which they can set.

    I'll mark it resolved, if anyone knows some way of "bringing the stack trace down a level", feel free to post it here. For now I will use this instead of the Error MessageBox.

  5. #5
    Fanatic Member BlindSniper's Avatar
    Join Date
    Jan 2011
    Location
    South Africa
    Posts
    865

    Re: [RESOLVED] Calling API's: Automatic error throwing

    Code:
      
            Dim st As New StackTrace
            st.GetFrame(1)
    I'm not sure what you mean by bringing it down a level but that is how you get the call stack trace.

  6. #6

    Thread Starter
    Fanatic Member
    Join Date
    Jul 2009
    Posts
    629

    Re: [RESOLVED] Calling API's: Automatic error throwing

    Minitech gave my answer in one of your replies, kind of a coincidence.

    I now use this, next to the other functions:
    Code:
    Public Sub CallError()
        ThrowError()
    End Sub
    
    <DebuggerStepThrough()> _
    Public Sub ThrowError
        Throw New Exception("Error!")
    End Sub

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width