[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
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
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
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. :D
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.
Re: [RESOLVED] Calling API's: Automatic error throwing
Minitech gave my answer in one of your replies, kind of a coincidence. :bigyello:
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